aboutsummaryrefslogtreecommitdiff
path: root/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface
diff options
context:
space:
mode:
Diffstat (limited to 'spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface')
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/Constants.java90
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/DOMUtils.java169
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/URLRewriter.java157
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/Utils.java51
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/XPathUtils.java162
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/ChecksInfoBean.java165
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/DataInfoBean.java541
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/HashInputDataInfo.java55
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/InitPropertiesBean.java36
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/SignerInfoBean.java127
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java57
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java44
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java381
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java55
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java50
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java214
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/listeners/XMLParserErrorHandler.java65
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/moainvoker/MOAInvoker.java92
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/HashInputDataServlet.java93
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/MOAServlet.java113
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/ReturnServlet.java129
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/SLRequest.java19
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/MOA2SL.java93
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/QName.java51
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/SL2MOA.java93
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/Utils.java129
26 files changed, 3231 insertions, 0 deletions
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/Constants.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/Constants.java
new file mode 100644
index 000000000..419f1fb9b
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/Constants.java
@@ -0,0 +1,90 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class Constants
+{
+ // System properties
+ public static final String SP_INIT_PROPS_LOC_ =
+ "at.gv.egovernment.moa.spss.slinterface.PropertiesLocation";
+
+ // Init properties
+
+ // TODO Revisit if constants can be removed
+ // public static final String IP_SL2MOA_STYLESHEET_ = "location.stylesheet.sl2moa";
+ // public static final String IP_MOA2SL_STYLESHEET_ = "location.stylesheet.moa2sl";
+ public static final String IP_SL_SCHEMA_ = "location.schema.sl";
+ public static final String IP_MOA_SCHEMA_ = "location.schema.moa";
+ public static final String IP_SLXHTML_SCHEMA_ = "location.schema.slxhtml";
+ public static final String IP_TEMP_DIR_ = "location.tempdir";
+ public static final String IP_SP_ENDPOINT_ = "service.sp.endpoint";
+ public static final String IP_SP_TRUSTPROFILEID_ = "service.sp.trustProfileId";
+ public static final String IP_RES_SHOWETSI_ = "result.showetsi";
+ public static final String IP_RES_SHOWSLMAN_ = "result.showslmanifest";
+
+ public static final String IP_REW_ = "rewrite";
+ public static final String IP_REW_PROXYURL_ = "rewrite.proxyURL";
+ public static final String IP_REW_PROXYURL_HOSTDUMMY_ = "rewrite.proxyURL.proxyhostDummy";
+ public static final String IP_REW_DNS_LOOKUP_PREFIX_ = "rewrite.dn.";
+ public static final String IP_REW_DNS_LOOKUP_DEFAULT_ = "rewrite.dn.default";
+ public static final String IP_REW_MOASL_URLPARAMNAME_ = "rewrite.MOASLUrlParamName";
+ public static final String IP_REW_MOASL_WEBAPPSERV_URL_ = "rewrite.MOASLWebAppServUrl";
+
+ // Logging hierarchies
+
+ public static final String LH_BASE_ = "slinterface";
+ public static final String LH_LISTENERS_ = LH_BASE_ + ".listeners";
+ public static final String LH_LISTENERS_XMLPARSER_ = LH_LISTENERS_ + ".xmlparser";
+ public static final String LH_FILTERS_ = LH_BASE_ + ".filters";
+ public static final String LH_SERVLETS_ = LH_BASE_ + ".servlets";
+ public static final String LH_BEANS_ = LH_BASE_ + ".beans";
+ public static final String LH_TEST_ = LH_BASE_ + ".test";
+
+ // Web service context parameters
+
+ public static final String WSCP_INIT_PROPS_ = "initProperties";
+ public static final String WSCP_INITPROPS_BEAN_ = "initPropertiesBean";
+ // TODO Revisit if constants can be removed
+ // public static final String WSCP_SL2MOA_TRANSFORMER_ = "sl2MoaTransformer";
+ // public static final String WSCP_MOA2SL_TRANSFORMER_ = "moa2SlTransformer";
+ public static final String WSCP_XMLPARSER_ = "xmlParser";
+ public static final String WSCP_URL_REWRITER_ = "urlRewriter";
+
+ // Security-Layer constants
+
+ public static final String SLC_NAME_HTTP_REQUEST_ = "http-security-layer-request";
+ public static final String SLC_NAME_XML_REQUEST_ = "XMLRequest";
+ public static final String SLC_NAME_DATA_URL_ = "DataURL";
+ public static final String SLC_NAME_STYLESHEET_URL_ = "StylesheetURL";
+ public static final String SLC_NAME_REDIRECT_URL_ = "RedirectURL";
+
+ // Namespace URIs
+
+ public static final String NSURI_SL_10_ = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#";
+ public static final String NSURI_SL_11_ = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#";
+ // TODO Change Namespace to final SL 1.2
+ public static final String NSURI_SL_12_ = "http://www.buergerkarte.at/namespaces/securitylayer/20031231#";
+ public static final String NSURI_MOA_12_ = "http://reference.e-government.gv.at/namespace/moa/20020822#";
+ public static final String NSURI_NAMESPACES_ = "http://www.w3.org/2000/xmlns/";
+ public static final String NSURI_XML_ = "http://www.w3.org/XML/1998/namespace";
+ public static final String NSURI_DSIG_ = "http://www.w3.org/2000/09/xmldsig#";
+ public static final String NSURI_XHTML_ = "http://www.w3.org/1999/xhtml";
+
+ // Namespace prefixes
+ public static final String NSPRE_SL_10_ = "sl10";
+ public static final String NSPRE_SL_11_ = "sl11";
+ public static final String NSPRE_SL_12_ = "sl12";
+ public static final String NSPRE_MOA_12_ = "moa";
+ public static final String NSPRE_DSIG_ = "dsig";
+ public static final String NSPRE_XHTML_ = "xhtml";
+
+ // MOA invoker constants
+
+ public static final String MI_SP_QNAME_ = "SignatureVerification";
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/DOMUtils.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/DOMUtils.java
new file mode 100644
index 000000000..814d7832e
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/DOMUtils.java
@@ -0,0 +1,169 @@
+/*
+ * Created on 28.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.xerces.parsers.DOMParser;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import at.gv.egovernment.moa.spss.slinterface.listeners.XMLParserErrorHandler;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class DOMUtils
+{
+ private static final String SAX_NAMESPACES_FEATURE = "http://xml.org/sax/features/namespaces";
+ private static final String XERCES_CREATE_ENTITY_REF_NODES_FEATURE =
+ "http://apache.org/xml/features/dom/create-entity-ref-nodes";
+ protected static final String XERCES_DEFER_NODE_EXPANSION_ =
+ "http://apache.org/xml/features/dom/defer-node-expansion";
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the first text node of the specified element.
+ *
+ * @param elem The element.
+ *
+ * @return the first text node of the specified element, or <code>null</code> if <code>element</code>
+ * equals <code>null</code>, or if the element has no text node.
+ */
+ public static String getText(Element elem)
+ {
+ if (elem == null) return null;
+ NodeList childNodes = elem.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++)
+ {
+ Node currNode = childNodes.item(i);
+ if (currNode.getNodeType() == Node.TEXT_NODE) return currNode.getNodeValue();
+ }
+ return null;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the first text node of the specified child element from the specified parent element.
+ *
+ * @param parent The parent.
+ *
+ * @param childNS The namespace of the child element.
+ *
+ * @param childLocName The local name of the child element.
+ *
+ * @return the first text node of the specified child, or <code>null</code> if <code>parent</code> equals
+ * <code>null</code> or has no child element with the specified namespace and local name, or if
+ * the child element has no text node.
+ */
+ public static String getChildText(Element parent, String childNS, String childLocName)
+ {
+ if (parent == null) return null;
+ Element child = getChildElem(parent, childNS, childLocName);
+ if (child == null) return null;
+ return getText(child);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the first child element of the specified parent with the specified namspace and local name.
+ *
+ * @param parent The parent.
+ *
+ * @param childNS The namespace of the child element to be searched for.
+ *
+ * @param childLocName The local name of the child element to be searched for.
+ *
+ * @return the first child element as described above, or <code>null</code> if <code>parent</code> is
+ * null or has no child elements with for the specified namespace and local name.
+ */
+ public static Element getChildElem(Element parent, String childNS, String childLocName)
+ {
+ List childElems = getChildElems(parent, childNS, childLocName, true);
+ return (childElems == null) ? null : (Element) childElems.get(0);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets all or the first child element(s) of the specified parent with the specified namspace and local
+ * name.
+ *
+ * @param parent The parent.
+ *
+ * @param childNS The namespace of the child elements to be searched for.
+ *
+ * @param childLocName The local name of the child elements to be searched for.
+ *
+ * @param firstOnly Specifies wheter only the first or all child elements with the specified namespace and
+ * local name should be returned.
+ *
+ * @return a <code>java.util.List</code> with objects of type <code>org.w3c.dom.Element</code>; each
+ * element in the list represents a child element as specified above. If <code>parent</code>
+ * equals <code>null</code>, or if there are no child elements as specified above, <code>null
+ * </code> will be returned.
+ */
+ public static List getChildElems(Element parent, String childNS, String childLocName, boolean firstOnly)
+ {
+ if (parent == null) return null;
+
+ ArrayList childElems = new ArrayList();
+ NodeList childNodes = parent.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++)
+ {
+ Node currNode = childNodes.item(i);
+ if (currNode.getNodeType() == Node.ELEMENT_NODE)
+ {
+ Element currElem = (Element) currNode;
+ if (childNS.equals(currElem.getNamespaceURI()) && childLocName.equals(currElem.getLocalName()))
+ {
+ childElems.add(currElem);
+ if (firstOnly) break;
+ }
+ }
+ }
+ return (childElems.size() == 0) ? null : childElems;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static Document parseWellFormed(InputStream is) throws Exception
+ {
+ DOMParser xmlParser = new DOMParser();
+ try
+ {
+ xmlParser.setFeature(SAX_NAMESPACES_FEATURE, true);
+ xmlParser.setFeature(XERCES_CREATE_ENTITY_REF_NODES_FEATURE, false);
+ xmlParser.setFeature(XERCES_DEFER_NODE_EXPANSION_, false);
+ xmlParser.setErrorHandler(new XMLParserErrorHandler(false, true, true));
+
+ }
+ catch (SAXException e)
+ {
+ String message = "Initialization of XML parser failed.";
+ throw new Exception(message, e);
+ }
+ try
+ {
+ xmlParser.parse(new InputSource(is));
+ return xmlParser.getDocument();
+ }
+ catch (Exception e)
+ {
+ String message = "Wellformed parsing failed.";
+ throw new Exception(message, e);
+ }
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/URLRewriter.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/URLRewriter.java
new file mode 100644
index 000000000..683851ff9
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/URLRewriter.java
@@ -0,0 +1,157 @@
+/*
+ * Created on 15.12.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Properties;
+
+import javax.servlet.http.HttpSession;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class URLRewriter
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_LISTENERS_);
+
+ Properties initProps_;
+
+ /**
+ * Flag indicating whether rewriting should take place or not.
+ */
+ boolean doRewrite_;
+
+ /**
+ * Class that manges the rewriting of URLs for the result pages. Necessary as workaround for the deploy-
+ * ment in the Federal Chancellory.
+ */
+ public URLRewriter(Properties initProps)
+ {
+ initProps_ = initProps;
+ doRewrite_ = Boolean.valueOf(initProps_.getProperty(Constants.IP_REW_)).booleanValue();
+ }
+
+ /**
+ * Rewrites the specified URL.
+ *
+ * @param url A URL relative to the root of the web application server containing MOA SL.
+ *
+ * @param session The session which will be considered in the rewritten URL.
+ *
+ * @return A URL fitting for the proxy component running at the Federal Chancellory.
+ */
+ public String rewrite(String url, HttpSession session)
+ {
+ if (doRewrite_)
+ {
+ // Get remote IP address and resolve to remote to remote domain name
+ String remoteAddr = (String)session.getAttribute("remoteAddr");
+ String remoteName = null;
+ if (remoteAddr != null)
+ {
+ remoteName = initProps_.getProperty(Constants.IP_REW_DNS_LOOKUP_PREFIX_ + remoteAddr);
+ logger_.debug("Remote address lookup succeeded for IP " + remoteAddr + ", using " + remoteName);
+ }
+ if (remoteName == null)
+ {
+ remoteName = initProps_.getProperty(Constants.IP_REW_DNS_LOOKUP_DEFAULT_);
+ logger_.debug("Remote address lookup failed for IP " + remoteAddr + ", using default: " + remoteName);
+ }
+
+ // Get proxy URL and replace proxy URL hostname placeholder with remote domain name
+ String proxyURLStr = initProps_.getProperty(Constants.IP_REW_PROXYURL_);
+ int pHStartIndex = proxyURLStr.indexOf(initProps_.getProperty(Constants.IP_REW_PROXYURL_HOSTDUMMY_));
+ proxyURLStr = proxyURLStr.substring(0, pHStartIndex)
+ + remoteName
+ + proxyURLStr.substring(pHStartIndex
+ + initProps_.getProperty(Constants.IP_REW_PROXYURL_HOSTDUMMY_).length());
+
+ String slInterfaceURLParamName = initProps_.getProperty(Constants.IP_REW_MOASL_URLPARAMNAME_);
+ String slInterfaceWebAppServURLStr = initProps_.getProperty(Constants.IP_REW_MOASL_WEBAPPSERV_URL_);
+
+ if (proxyURLStr == null ||
+ slInterfaceURLParamName == null ||
+ slInterfaceWebAppServURLStr == null ||
+ "".equals(proxyURLStr.trim()) ||
+ "".equals(slInterfaceURLParamName.trim()) ||
+ "".equals(slInterfaceWebAppServURLStr.trim()))
+ {
+ logger_.warn("Some params for URL rewriting are not available; rewriting disabled:" +
+ " proxyURL: \"" + proxyURLStr + "\"," +
+ " slInterfaceURLParamName: \"" + slInterfaceURLParamName + "\"," +
+ " slInterfaceWebAppServURLStr: \"" + slInterfaceWebAppServURLStr + "\"");
+ return url;
+ }
+
+ URL slInterfaceURL = null;
+ try
+ {
+ slInterfaceURL = new URL(slInterfaceWebAppServURLStr + url);
+ }
+ catch (MalformedURLException e)
+ {
+ logger_.warn("Parameter \"slInterfaceURL\" is not a valid URL: \"" + slInterfaceWebAppServURLStr + url + "\"");
+ return url;
+ }
+ URL proxyURL = null;
+ try
+ {
+ proxyURL = new URL(proxyURLStr);
+ }
+ catch (MalformedURLException e)
+ {
+ logger_.warn("Parameter \"proxyURL\" is not a valid URL: \"" + proxyURLStr + "\"");
+ return url;
+ }
+
+ String sessionId = session.getId();
+ String sessionIdParam = (sessionId != null) ? (";" + "jsessionid=" + sessionId) : "";
+ String returnValue =
+ proxyURL.getProtocol() +
+ "://" +
+ proxyURL.getHost() +
+ ((proxyURL.getPort() != -1) ? (":" + proxyURL.getPort()) : "") +
+ proxyURL.getPath() +
+ ((proxyURL.getQuery() != null) ? "?" + proxyURL.getQuery() + "&" : "?") +
+ slInterfaceURLParamName + "=" +
+ slInterfaceURL.getProtocol() +
+ "://" +
+ slInterfaceURL.getHost() +
+ ((slInterfaceURL.getPort() != -1) ? (":" + slInterfaceURL.getPort()) : "") +
+ slInterfaceURL.getPath() +
+ sessionIdParam +
+ ((slInterfaceURL.getQuery() != null) ? "?" + escapeQueryPart(slInterfaceURL.getQuery()) : "");
+
+ logger_.debug("Rewritten URL: " + returnValue);
+ return returnValue;
+ }
+ else
+ {
+ logger_.debug("URL rewriting disabled via configuration. URL \"" + url + "\" remains unchanged.");
+ return url;
+ }
+ }
+
+ private String escapeQueryPart(String query)
+ {
+ StringBuffer querySB = new StringBuffer();
+ for (int i = 0; i < query.length(); i++)
+ {
+ if (query.charAt(i) == '&')
+ {
+ querySB.append("%26");
+ }
+ else
+ {
+ querySB.append(query.charAt(i));
+ }
+ }
+ return querySB.toString();
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/Utils.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/Utils.java
new file mode 100644
index 000000000..50ae5dc03
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/Utils.java
@@ -0,0 +1,51 @@
+/*
+ * Created on 25.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class Utils
+{
+ public static byte[] readFromInputStream(InputStream inputStream) throws IOException
+ {
+ byte[] currentBytes = new byte[500];
+ int bytesRead;
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ do
+ {
+ bytesRead = inputStream.read(currentBytes);
+ if (bytesRead > 0)
+ {
+ result.write(currentBytes, 0, bytesRead);
+ }
+ }
+ while (bytesRead != -1);
+ return result.toByteArray();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static void transferStreams(InputStream in, OutputStream out) throws IOException
+ {
+ byte[] currentBytes = new byte[500];
+ int bytesRead;
+ do
+ {
+ bytesRead = in.read(currentBytes);
+ if (bytesRead > 0)
+ {
+ out.write(currentBytes, 0, bytesRead);
+ }
+ }
+ while (bytesRead != -1);
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/XPathUtils.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/XPathUtils.java
new file mode 100644
index 000000000..16e4938ed
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/XPathUtils.java
@@ -0,0 +1,162 @@
+/*
+ * Created on 02.12.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface;
+
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+import org.apache.xml.utils.PrefixResolverDefault;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class XPathUtils
+{
+ /**
+ * The XPath context for the XPath engine.
+ */
+ protected XPathContext xPathContext_;
+
+ /**
+ * The prefix resolver for the XPath engine.
+ */
+ protected PrefixResolver prefixResolver_;
+
+ /**
+ * The XPath engine.
+ */
+ protected XPath xPath_;
+
+ /* ==================================================================================================== */
+
+ public void setupContext(String xPathExpr, Node namespaceNode, String additionalNSPrefixes)
+ throws Exception
+ {
+
+ try
+ {
+ // Set up a new evaluation context
+ xPathContext_ = new XPathContext();
+
+ // Set up the namespace prefix resolver for the XPath engine
+ prefixResolver_ = new PrefixResolver(namespaceNode, additionalNSPrefixes);
+
+ // Initialize XPath engine
+ xPath_ = new XPath(xPathExpr, null, prefixResolver_, XPath.SELECT, null);
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Setting up XPath evaluation context failed.", e);
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public NodeList selectNodeSet(Node contextNode) throws Exception
+ {
+ XObject xObject;
+ try
+ {
+ xObject = xPath_.execute(xPathContext_, contextNode, prefixResolver_);
+ return xObject.nodelist();
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Executing XPath expression failed.", e);
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public boolean selectBoolean(Node contextNode) throws Exception
+ {
+ XObject xObject;
+ try
+ {
+ xObject = xPath_.execute(xPathContext_, contextNode, prefixResolver_);
+ return xObject.bool();
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Executing XPath expression failed.", e);
+ }
+ }
+
+ /* ==================================================================================================== */
+
+ /**
+ * Special extension of the {@link org.apache.xml.utils.PrefixResolverDefault} interface. Used to
+ * configure the Apache Xalan XPath engine which is employed as the backbone of this class.
+ */
+ protected class PrefixResolver extends PrefixResolverDefault
+ {
+
+ /**
+ * Contains the additionally specified namespace prefix (key) to namespace URI (value) attributions.
+ */
+ protected HashMap additionalNSPrefixesMap_;
+
+ /* ================================================================================================== */
+
+ /**
+ * Basic constructor.
+ *
+ * @param xpathExpressionContext The namespace declarations in scope for this node will be used to get
+ * the namespace uri for a prefix specified in the XPath expression.
+ *
+ * @param additionalNSPrefixes Allows the specification of additional prefix to uri attributions apart
+ * from the declarations in scope for the parameter <code>
+ * xpathExpressionContext</code>. May be <code>null</code>.
+ */
+ public PrefixResolver(Node xpathExpressionContext, String additionalNSPrefixes) throws Exception
+ {
+ super(xpathExpressionContext);
+ additionalNSPrefixesMap_ = new HashMap();
+
+ // Register the specified additional namespace prefix to namespace uri attributions
+ if (additionalNSPrefixes != null)
+ {
+ StringTokenizer tokenizer = new StringTokenizer(additionalNSPrefixes, " ");
+ while (tokenizer.hasMoreTokens())
+ {
+ String prefix = tokenizer.nextToken();
+ if (!tokenizer.hasMoreTokens())
+ {
+
+ // There must be an even number of tokens in the string
+ throw new Exception("Parameter \"additionalNSPrefixes\" must have an even number of tokens.");
+ }
+ String uri = tokenizer.nextToken();
+ additionalNSPrefixesMap_.put(prefix, uri);
+ }
+ }
+ }
+
+ /* -------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the namespace uri for the specified namespace prefix. The additionally specified prefixes
+ * overrule the prefixes found in the specified namespace node.
+ *
+ * @param prefix The namespace prefix for which a namespace uri should be found.
+ *
+ * @return the namespace uri for the specified namespace prefix.
+ */
+ public String getNamespaceForPrefix(String prefix)
+ {
+ String additionalURI = (String) additionalNSPrefixesMap_.get(prefix);
+ return (additionalURI != null)
+ ? additionalURI
+ : super.getNamespaceForPrefix(prefix);
+ }
+ }
+}
+
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/ChecksInfoBean.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/ChecksInfoBean.java
new file mode 100644
index 000000000..00c9fd517
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/ChecksInfoBean.java
@@ -0,0 +1,165 @@
+/*
+ * Created on 27.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.beans;
+
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.DOMUtils;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ChecksInfoBean
+{
+ private static final String SIG_CHECK_ELEM_ = "SignatureCheck";
+ private static final String SIGMF_CHECK_ELEM_ = "SignatureManifestCheck";
+ private static final String XMLDSIGMF_CHECK_ELEM_ = "XMLDSIGManifestCheck";
+ private static final String CERT_CHECK_ELEM_ = "CertificateCheck";
+ private static final String CODE_ELEM_ = "Code";
+ private static final String INFO_ELEM_ = "Info";
+ private static final String FAILEDREF_ELEM_ = "FailedReference";
+ private static final String REFSIGREF_ELEM_ = "ReferringSigReference";
+
+ private Element sigCheckElem_;
+ private int sigCheckFaildRefCount_;
+
+ private Element sigMFCheckElem_;
+ private int sigMFCheckFaildRefCount_;
+
+ private List xmldsigMFCheckElems_;
+ private int xmldsigMFCheckCount_;
+ private int xmldsigMFCheckFaildRefCount_;
+
+ private Element certCheckElem_;
+
+ /**
+ * Creates a bean with information about the checks executed for the verified xml signature.
+ *
+ * @pre slResponseDoc has been validated.
+ */
+ public ChecksInfoBean(Document slResponseDoc)
+ {
+ Element verifyXMLResponseElem = slResponseDoc.getDocumentElement();
+ sigCheckElem_ = DOMUtils.getChildElem(
+ verifyXMLResponseElem, Constants.NSURI_SL_11_, SIG_CHECK_ELEM_);
+ sigMFCheckElem_ = DOMUtils.getChildElem(
+ verifyXMLResponseElem, Constants.NSURI_SL_11_, SIGMF_CHECK_ELEM_);
+ xmldsigMFCheckElems_ = DOMUtils.getChildElems(
+ verifyXMLResponseElem, Constants.NSURI_SL_11_, XMLDSIGMF_CHECK_ELEM_, false);
+ certCheckElem_ = DOMUtils.getChildElem(
+ verifyXMLResponseElem, Constants.NSURI_SL_11_, CERT_CHECK_ELEM_);
+
+ sigCheckFaildRefCount_ = 0;
+ sigMFCheckFaildRefCount_ = 0;
+ xmldsigMFCheckFaildRefCount_ = 0;
+ xmldsigMFCheckCount_ = 0;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getSigCheckCode()
+ {
+ return DOMUtils.getChildText(sigCheckElem_, Constants.NSURI_SL_11_, CODE_ELEM_);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void setSigCheckFailedRefCount(int count)
+ {
+ sigCheckFaildRefCount_ = count;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getSigCheckFailedRef()
+ {
+ Element info = DOMUtils.getChildElem(sigCheckElem_, Constants.NSURI_SL_11_, INFO_ELEM_);
+ if (info == null) return null;
+ List failedRefElems = DOMUtils.getChildElems(info, Constants.NSURI_SL_11_, FAILEDREF_ELEM_, false);
+ if (failedRefElems == null || failedRefElems.size() <= sigCheckFaildRefCount_) return null;
+ return DOMUtils.getText((Element)failedRefElems.get(sigCheckFaildRefCount_));
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getSigMFCheckCode()
+ {
+ return DOMUtils.getChildText(sigMFCheckElem_, Constants.NSURI_SL_11_, CODE_ELEM_);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void setSigMFCheckFailedRefCount(int count)
+ {
+ sigMFCheckFaildRefCount_ = count;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getSigMFCheckFailedRef()
+ {
+ Element info = DOMUtils.getChildElem(sigMFCheckElem_, Constants.NSURI_SL_11_, INFO_ELEM_);
+ if (info == null) return null;
+ List failedRefElems = DOMUtils.getChildElems(info, Constants.NSURI_SL_11_, FAILEDREF_ELEM_, false);
+ if (failedRefElems == null || failedRefElems.size() <= sigMFCheckFaildRefCount_) return null;
+ return DOMUtils.getText((Element)failedRefElems.get(sigMFCheckFaildRefCount_));
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void setXmldsigMFCheckCount(int count)
+ {
+ xmldsigMFCheckCount_ = count;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void setXmldsigMFCheckFailedRefCount(int count)
+ {
+ xmldsigMFCheckFaildRefCount_ = count;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getXmldsigMFCheckCode()
+ {
+ Element xmldsigMFCheckElem = (Element)xmldsigMFCheckElems_.get(xmldsigMFCheckCount_);
+ return DOMUtils.getChildText(xmldsigMFCheckElem, Constants.NSURI_SL_11_, CODE_ELEM_);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getXmldsigMFCheckFailedRef()
+ {
+ Element xmldsigMFCheckElem = (Element)xmldsigMFCheckElems_.get(xmldsigMFCheckCount_);
+ Element info = DOMUtils.getChildElem(xmldsigMFCheckElem, Constants.NSURI_SL_11_, INFO_ELEM_);
+ if (info == null) return null;
+ List failedRefElems = DOMUtils.getChildElems(info, Constants.NSURI_SL_11_, FAILEDREF_ELEM_, false);
+ if (failedRefElems == null || failedRefElems.size() <= xmldsigMFCheckFaildRefCount_) return null;
+ return DOMUtils.getText((Element)failedRefElems.get(xmldsigMFCheckFaildRefCount_));
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getXmldsigMFCheckReferringSigRef()
+ {
+ Element xmldsigMFCheckElem = (Element)xmldsigMFCheckElems_.get(xmldsigMFCheckCount_);
+ Element info = DOMUtils.getChildElem(xmldsigMFCheckElem, Constants.NSURI_SL_11_, INFO_ELEM_);
+ if (info == null) return null;
+ return DOMUtils.getChildText(info, Constants.NSURI_SL_11_, REFSIGREF_ELEM_);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getCertCheckCode()
+ {
+ return DOMUtils.getChildText(certCheckElem_, Constants.NSURI_SL_10_, CODE_ELEM_);
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/DataInfoBean.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/DataInfoBean.java
new file mode 100644
index 000000000..570f3fb15
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/DataInfoBean.java
@@ -0,0 +1,541 @@
+/*
+ * Created on 27.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.beans;
+
+import iaik.utils.Util;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Random;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+import org.apache.log4j.Logger;
+import org.apache.xerces.parsers.DOMParser;
+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.InputSource;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.DOMUtils;
+import at.gv.egovernment.moa.spss.slinterface.URLRewriter;
+import at.gv.egovernment.moa.spss.slinterface.XPathUtils;
+import at.gv.egovernment.moa.spss.slinterface.moainvoker.MOAInvoker;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class DataInfoBean implements HttpSessionBindingListener
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_BEANS_);
+
+ // MOA
+ private static final String HID_ELEM_ = "HashInputData";
+ private static final String B64CONT_ELEM_ = "Base64Content";
+ private static final String XMLCONT_ELEM_ = "XMLContent";
+ private static final String SIGLOC_ELEM_ = "VerifySignatureLocation";
+
+ // XMLDSIG
+ private static final String TYPE_ATTR_ = "Type";
+ private static final String URI_ATTR_ = "URI";
+
+ // XHTML
+ private static final String SRC_ATTR_ = "src";
+ private static final String HTML_ELEM_ = "html";
+
+ private static final String HID_URL_PREFIX_ = "/showdata?hidCount=";
+
+ private static final String XPATH_ALL_IMG_ = "//" + Constants.NSPRE_XHTML_ + ":img";
+ private static final String XPATH_ALL_REF_ = "./" + Constants.NSPRE_DSIG_ + ":SignedInfo/" +
+ Constants.NSPRE_DSIG_ + ":Reference";
+ private static final String XPATH_SIG_ENV_CONTENT_ = "/" + Constants.NSPRE_MOA_12_ + ":VerifyXMLSignatureRequest/" +
+ Constants.NSPRE_MOA_12_ + ":VerifySignatureInfo/" + Constants.NSPRE_MOA_12_ + ":VerifySignatureEnvironment/*";
+
+ private static final String SLXHTML_TYPE_PREFIX_ = "http://www.buergerkarte.at/specifications/" +
+ "Security-Layer/20031113?Name=SignedImage&InstanceDocRef=";
+
+ private static final String ETSI_TYPE_ = "http://uri.etsi.org/01903/v1.1.1#SignedProperties";
+ private static final String SLMANIFEST_TYPE_ =
+ "http://www.buergerkarte.at/specifications/Securitylayer/20020225#SignatureManifest";
+
+ ServletContext context_;
+ String contextPath_;
+ HttpSession session_;
+
+ Properties initProps_;
+
+ /**
+ * Contains objects of type {@link HashInputDataInfo}.
+ */
+ List hashInputDataInfos_;
+
+ int hashInputDataCount_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public DataInfoBean(Document moaRequestDoc, Document moaResponseDoc, String contextPath, HttpSession session,
+ ServletContext context) throws Exception
+ {
+ context_ = context;
+ contextPath_ = contextPath;
+ session_ = session;
+ initProps_ = (Properties) context_.getAttribute(Constants.WSCP_INIT_PROPS_);
+
+ hashInputDataInfos_ = new ArrayList();
+ int hashInputDataCount_ = 0;
+
+ Element moaResponseElem = moaResponseDoc.getDocumentElement();
+ List hidElems = DOMUtils.getChildElems(moaResponseElem, Constants.NSURI_MOA_12_, HID_ELEM_, false);
+
+ String tempDir = initProps_.getProperty(Constants.IP_TEMP_DIR_);
+ if (tempDir == null)
+ {
+ String message = "Init property \"" + Constants.IP_TEMP_DIR_ + "\" not set.";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ Random random = new Random();
+ for (int i = 0; i < hidElems.size(); i++)
+ {
+ // Open file for current hash input data
+ String currHidFileNameStr = tempDir + session_.getId() + "_" + System.currentTimeMillis() + "_" +
+ random.nextLong();
+ currHidFileNameStr = context_.getRealPath(currHidFileNameStr);
+ FileOutputStream currHidFOS;
+ try
+ {
+ currHidFOS = new FileOutputStream(currHidFileNameStr);
+ }
+ catch (IOException e)
+ {
+ String message = "Cannot open file \"" + currHidFileNameStr + "\".";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ // Write HID to file
+ Element currHidElem = (Element) hidElems.get(i);
+ Element base64ContentElem = DOMUtils.getChildElem(currHidElem, Constants.NSURI_MOA_12_, B64CONT_ELEM_);
+ if (base64ContentElem != null)
+ {
+ // HID is base64
+
+ String base64ContentText = DOMUtils.getText(base64ContentElem);
+ byte[] content = Util.Base64Decode(base64ContentText.getBytes());
+ try
+ {
+ currHidFOS.write(content);
+ currHidFOS.close();
+ }
+ catch (IOException e)
+ {
+ String message = "Cannot write to file \"" + currHidFileNameStr + "\".";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+ }
+ else
+ {
+ // HID is XML
+
+ // TODO treatment of XML content
+ throw new RuntimeException("XML content not support yet.");
+ }
+
+ hashInputDataInfos_.add(new HashInputDataInfo(currHidFileNameStr));
+ }
+ logger_.debug("Finnished writing hash input data to files.");
+
+ // Check if hids are slxhtml documents; mark them appropriately
+ try
+ {
+ Map signedImages = getSignedImages(moaRequestDoc, hashInputDataInfos_);
+ for (int i = 0; i < hashInputDataInfos_.size(); i++)
+ {
+ HashInputDataInfo currHid = (HashInputDataInfo) hashInputDataInfos_.get(i);
+ FileInputStream currHidIS = new FileInputStream(currHid.filename_);
+ checkImages(currHidIS, currHid, signedImages);
+ }
+ }
+ catch (Exception e)
+ {
+ String message = "Performing SLXHTML checks failed.";
+ logger_.error(message, e);
+ throw new Exception(message, e);
+ }
+ logger_.debug("Finnished checking hash input data for slxhtml conformity.");
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void valueBound(HttpSessionBindingEvent event)
+ {
+ // Do nothing.
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void valueUnbound(HttpSessionBindingEvent event)
+ {
+ // Delete all temporary hash input data files
+ for (int i = 0; i < hashInputDataInfos_.size(); i++)
+ {
+ String currFileStr = ((HashInputDataInfo) hashInputDataInfos_.get(i)).filename_;
+ File currFile = new File(currFileStr);
+ currFile.delete();
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void setHashInputDataCount(int count)
+ {
+ hashInputDataCount_ = count;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getHashInputDataFilename()
+ {
+ HashInputDataInfo currHid = (HashInputDataInfo) hashInputDataInfos_.get(hashInputDataCount_);
+ return (currHid == null) ? null : currHid.filename_;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getHashInputDataURL()
+ {
+ return (hashInputDataInfos_.size() > hashInputDataCount_)
+ ? HID_URL_PREFIX_ + hashInputDataCount_
+ : null;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public boolean getShowHashInputData()
+ {
+ HashInputDataInfo currHid = (HashInputDataInfo) hashInputDataInfos_.get(hashInputDataCount_);
+ return (currHid == null) ? false : currHid.doShow_;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public boolean getIsSLXHTMLDocument()
+ {
+ HashInputDataInfo currHid = (HashInputDataInfo) hashInputDataInfos_.get(hashInputDataCount_);
+ return (currHid == null) ? false : currHid.isSLXHTMLDocument_;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private Document parseSLXHTMLDocument(InputStream docIS)
+ {
+ DOMParser xmlParser = (DOMParser) context_.getAttribute(Constants.WSCP_XMLPARSER_);
+ InputSource docInputSource = new InputSource(docIS);
+ Document parsedDoc = null;
+ try
+ {
+ xmlParser.parse(docInputSource);
+ parsedDoc = xmlParser.getDocument();
+ }
+ catch (Exception e)
+ {
+ // Exception shows that document is not a valid SLXHTML document; return null in that case
+ logger_.debug("HashInputData is not a valid SLXHTML document.", e);
+ return null;
+ }
+
+ Element docElem = parsedDoc.getDocumentElement();
+ if (docElem.getNamespaceURI() != Constants.NSURI_XHTML_ || docElem.getLocalName() != HTML_ELEM_)
+ {
+ return null;
+ }
+
+ return parsedDoc;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private void checkImages(InputStream hidIS, HashInputDataInfo hid, Map signedImages) throws Exception
+ {
+ // Parse hidIS
+ Document slxhtmlDoc = parseSLXHTMLDocument(hidIS);
+ if (slxhtmlDoc == null) return;
+
+ // Get all img elements of slxhtml document
+ XPathUtils xpUtils = new XPathUtils();
+ String additionalNSPrefixes = Constants.NSPRE_XHTML_ + " " + Constants.NSURI_XHTML_;
+ xpUtils.setupContext(XPATH_ALL_IMG_, slxhtmlDoc.getDocumentElement(), additionalNSPrefixes);
+ NodeList imgTags = xpUtils.selectNodeSet(slxhtmlDoc);
+
+ // Check if all img elements have corresponding slxhtml signed images
+ boolean allImgsSigned = true;
+ for (int i = 0; i < imgTags.getLength(); i++)
+ {
+ Element currImgElem = (Element) imgTags.item(i);
+ String uri = currImgElem.getAttribute(SRC_ATTR_);
+ if (!signedImages.containsKey(uri))
+ {
+ allImgsSigned = false;
+ break;
+ }
+ }
+
+ // Mark all corresponding slxhtml signed images as not to be shown
+ if (allImgsSigned)
+ {
+ for (int i = 0; i < imgTags.getLength(); i++)
+ {
+ Element currImgElem = (Element) imgTags.item(i);
+ String uri = currImgElem.getAttribute(SRC_ATTR_);
+ HashInputDataInfo currHidi = (HashInputDataInfo) signedImages.get(uri);
+ currHidi.doShow_ = false;
+ }
+ }
+
+ if (allImgsSigned)
+ {
+ // Change the src attributes of all img tags so that they refer to the temporary names
+ for (int i = 0; i < imgTags.getLength(); i++)
+ {
+ Element currImgElem = (Element) imgTags.item(i);
+ String uri = currImgElem.getAttribute(SRC_ATTR_);
+ HashInputDataInfo currHidi = (HashInputDataInfo) signedImages.get(uri);
+
+ Attr srcAttr = currImgElem.getAttributeNode(SRC_ATTR_);
+ int slashPos = currHidi.filename_.lastIndexOf(System.getProperty("file.separator"));
+
+// Properties initProps = (Properties) context_.getAttribute(Constants.WSCP_INIT_PROPS_);
+// String tempDir = initProps.getProperty(Constants.IP_TEMP_DIR_);
+// String newSrcAttrValue = "." + tempDir + currHidi.filename_.substring(slashPos + 1);
+
+ Properties initProps = (Properties) context_.getAttribute(Constants.WSCP_INIT_PROPS_);
+ String tempDir = initProps.getProperty(Constants.IP_TEMP_DIR_);
+ URLRewriter urlRewriter = (URLRewriter) context_.getAttribute(Constants.WSCP_URL_REWRITER_);
+ String newSrcAttrValue = urlRewriter.rewrite(
+ contextPath_ + tempDir + currHidi.filename_.substring(slashPos + 1), session_);
+
+ srcAttr.setNodeValue(newSrcAttrValue);
+ }
+
+ // Mark hid as slxhtml document
+ hid.isSLXHTMLDocument_ = true;
+
+ // Serialize modified slxhtml document to temporary file location
+ FileOutputStream slxhtmlFOS = new FileOutputStream(hid.filename_);
+ MOAInvoker.serializeDocument(slxhtmlDoc, slxhtmlFOS);
+ slxhtmlFOS.close();
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private Map getSignedImages(Document moaRequestDoc, List hashInputDataInfos) throws Exception
+ {
+ // Get signature from MOA request
+ Element signatureElem = getSignature(moaRequestDoc);
+
+ // Get all signature references from MOA request
+ XPathUtils xpUtils = new XPathUtils();
+ String additionalNSPrefixes = Constants.NSPRE_DSIG_ + " " + Constants.NSURI_DSIG_;
+ xpUtils.setupContext(XPATH_ALL_REF_, signatureElem, additionalNSPrefixes);
+ NodeList dsigRefs = xpUtils.selectNodeSet(signatureElem);
+
+ // Check signature references for slxhtml images
+ HashMap imgHids = new HashMap(dsigRefs.getLength());
+ for (int i = 0; i < dsigRefs.getLength(); i++)
+ {
+ Element currRef = (Element) dsigRefs.item(i);
+ String type = currRef.getAttribute(TYPE_ATTR_);
+ if (type != null && type.startsWith(SLXHTML_TYPE_PREFIX_))
+ {
+ String uri = currRef.getAttribute(URI_ATTR_);
+ Set referredHids = createReferredHidsSet(type);
+ HashInputDataInfo currHidi = (HashInputDataInfo)hashInputDataInfos.get(i);
+ currHidi.uri_ = uri;
+ currHidi.referredHids_ = referredHids;
+ currHidi.isSLXHTMLImage_ = true;
+ imgHids.put(uri, currHidi);
+ }
+ }
+
+ // Check signature references if they refer to etsi attributes or to a SL manifest
+ for (int i = 0; i < dsigRefs.getLength(); i++)
+ {
+ Element currRef = (Element) dsigRefs.item(i);
+ String type = currRef.getAttribute(TYPE_ATTR_);
+ if (type != null && type.equals(ETSI_TYPE_))
+ {
+ HashInputDataInfo currHidi = (HashInputDataInfo)hashInputDataInfos.get(i);
+ currHidi.doShow_ = new Boolean(initProps_.getProperty(Constants.IP_RES_SHOWETSI_).trim()).booleanValue();
+ }
+ if (type != null && type.equals(SLMANIFEST_TYPE_))
+ {
+ HashInputDataInfo currHidi = (HashInputDataInfo)hashInputDataInfos.get(i);
+ currHidi.doShow_ = new Boolean(initProps_.getProperty(Constants.IP_RES_SHOWSLMAN_).trim()).booleanValue();
+ }
+ }
+
+ return imgHids;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private Set createReferredHidsSet(String type) throws Exception
+ {
+ HashSet set = new HashSet();
+ String typeSuffix = type.substring(SLXHTML_TYPE_PREFIX_.length());
+ StringTokenizer tokenizer = new StringTokenizer(typeSuffix, ",");
+ while (tokenizer.hasMoreTokens())
+ {
+ try
+ {
+ set.add(new Integer(tokenizer.nextToken()));
+ }
+ catch (NumberFormatException e)
+ {
+ String message = "Signed image type attribute \"" + type + "\" is malformed.";
+ logger_.error(message, e);
+ throw new Exception(message, e);
+ }
+ }
+ return set;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private Element getSignature(Document moaRequestDoc) throws Exception
+ {
+ // Get signature environment content
+ NodeList contentNL;
+ try
+ {
+ XPathUtils xpUtils = new XPathUtils();
+ String addNSPrefixes = Constants.NSPRE_MOA_12_ + " " + Constants.NSURI_MOA_12_;
+ xpUtils.setupContext(XPATH_SIG_ENV_CONTENT_, moaRequestDoc, addNSPrefixes);
+ contentNL = xpUtils.selectNodeSet(moaRequestDoc);
+ }
+ catch (Exception e)
+ {
+ String message = "Cannot find signature environment content.";
+ logger_.error(message);
+ throw new Exception(message, e);
+ }
+ if (contentNL.getLength() == 0)
+ {
+ String message = "Cannot find signature environment content.";
+ logger_.error(message);
+ throw new Exception(message);
+ }
+ Element contentElem = (Element) contentNL.item(0);
+
+ // Get signature environment document from signature environment content
+ String contentElemLocName = contentElem.getLocalName();
+ Element sigEnvElem = null;
+ Element oldDocElem = null;
+ if (XMLCONT_ELEM_.equals(contentElemLocName))
+ {
+ // XML content
+ NodeList contentNodes = contentElem.getChildNodes();
+ for (int i = 0; i < contentNodes.getLength(); i++)
+ {
+ Node currContNode = (Node) contentNodes.item(i);
+ if (currContNode.getNodeType() == Node.ELEMENT_NODE)
+ {
+ sigEnvElem = (Element) currContNode;
+ oldDocElem = (Element) moaRequestDoc.replaceChild(sigEnvElem, moaRequestDoc.getDocumentElement());
+ break;
+ }
+ }
+ }
+ else if (B64CONT_ELEM_.equals(contentElemLocName))
+ {
+ // Base64 content
+ String base64ContStr = DOMUtils.getText(contentElem);
+ byte[] contBytes = Util.Base64Decode(base64ContStr.getBytes());
+ ByteArrayInputStream contBIS = new ByteArrayInputStream(contBytes);
+ Document sigEnvDoc;
+ try
+ {
+ sigEnvDoc = DOMUtils.parseWellFormed(contBIS);
+ }
+ catch (Exception e)
+ {
+ String message = "Cannot parse signature environment from base64 content.";
+ logger_.error(message);
+ throw new Exception(message, e);
+ }
+ sigEnvElem = sigEnvDoc.getDocumentElement();
+ }
+ else
+ {
+ // LocRef content
+ String locRef = DOMUtils.getText(contentElem);
+ URL locRefURL = new URL(locRef);
+ InputStream contentIS = locRefURL.openStream();
+ Document sigEnvDoc;
+ try
+ {
+ sigEnvDoc = DOMUtils.parseWellFormed(contentIS);
+ }
+ catch (Exception e)
+ {
+ String message = "Cannot parse signature environment from location reference content.";
+ logger_.error(message);
+ throw new Exception(message, e);
+ }
+ sigEnvElem = sigEnvDoc.getDocumentElement();
+ }
+
+ // Get signature form signature environment document
+ Element sigInfoElem = (Element) contentElem.getParentNode().getParentNode();
+ Element sigLocElem = DOMUtils.getChildElem(sigInfoElem, Constants.NSURI_MOA_12_, SIGLOC_ELEM_);
+ String sigLocXPath = DOMUtils.getText(sigLocElem);
+ NodeList sigElemNL;
+ try
+ {
+ XPathUtils xpUtils = new XPathUtils();
+ xpUtils.setupContext(sigLocXPath, sigLocElem, null);
+ sigElemNL = xpUtils.selectNodeSet(sigEnvElem);
+ }
+ catch (Exception e)
+ {
+ String message = "Cannot get signature at location \"" + sigLocXPath + "\" from signature environment.";
+ logger_.error(message);
+ throw new Exception(message, e);
+ }
+ if (sigElemNL.getLength() != 1 || ((Node) sigElemNL.item(0)).getNodeType() != Node.ELEMENT_NODE)
+ {
+ String message = "Cannot get signature at location \"" + sigLocXPath + "\" from signature environment.";
+ logger_.error(message);
+ throw new Exception(message);
+ }
+
+ if (oldDocElem != null) moaRequestDoc.replaceChild(oldDocElem, moaRequestDoc.getDocumentElement());
+
+ return (Element) sigElemNL.item(0);
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/HashInputDataInfo.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/HashInputDataInfo.java
new file mode 100644
index 000000000..e2cb27ab3
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/HashInputDataInfo.java
@@ -0,0 +1,55 @@
+/*
+ * Created on 02.12.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.beans;
+
+import java.util.Set;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class HashInputDataInfo
+{
+ /**
+ * The name of the temporary file in which this data is stored.
+ */
+ public String filename_;
+
+ /**
+ * Is this HID a SLXHTML document?
+ */
+ public boolean isSLXHTMLDocument_;
+
+ /**
+ * Is this HID a SLXHTML signed image?
+ */
+ public boolean isSLXHTMLImage_;
+
+ /**
+ * Show HID in result presentation?
+ */
+ public boolean doShow_;
+
+ /**
+ * The URI attribute value of the dsig:Reference corresponding with this HID.
+ */
+ public String uri_;
+
+ /**
+ * In case that this ID is a SLXHTML signed image, this set contains objects of type <code>Integer</code>,
+ * indicating the SLXHTML HIDs where this image is referenced.
+ */
+ public Set referredHids_;
+
+ public HashInputDataInfo(String filename)
+ {
+ filename_ = filename;
+ isSLXHTMLDocument_ = false;
+ isSLXHTMLImage_ = false;
+ doShow_ = true;
+ uri_ = null;
+ referredHids_ = null;
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/InitPropertiesBean.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/InitPropertiesBean.java
new file mode 100644
index 000000000..8cb7e0a41
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/InitPropertiesBean.java
@@ -0,0 +1,36 @@
+package at.gv.egovernment.moa.spss.slinterface.beans;
+
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@siemens.com)
+ */
+public class InitPropertiesBean
+{
+ private Properties initProps_;
+
+ private static Logger logger_ = Logger.getLogger(Constants.LH_BEANS_);
+
+ public InitPropertiesBean(Properties props)
+ {
+ initProps_ = props;
+ }
+
+ public String getMOASLWebAppURL()
+ {
+ String webAppServerURLProp = initProps_.getProperty(Constants.IP_REW_MOASL_WEBAPPSERV_URL_);
+ logger_.debug("MOA SL Web application server URL property: " + webAppServerURLProp);
+ if (webAppServerURLProp == null || webAppServerURLProp.trim().length() == 0)
+ {
+ String defaultWebAppServerURL = "http://localhost:8080";
+ logger_.info("MOA SL Web application server URL property not available, using default (" + defaultWebAppServerURL + ")");
+ return defaultWebAppServerURL;
+ }
+ else return webAppServerURLProp;
+
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/SignerInfoBean.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/SignerInfoBean.java
new file mode 100644
index 000000000..2893b2ac3
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/beans/SignerInfoBean.java
@@ -0,0 +1,127 @@
+/*
+ * Created on 27.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.beans;
+
+import iaik.asn1.ObjectID;
+import iaik.asn1.structures.Name;
+import iaik.utils.RFC2253NameParser;
+import iaik.utils.RFC2253NameParserException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.DOMUtils;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class SignerInfoBean
+{
+ private static final String SIGNERINFO_ELEM_ = "SignerInfo";
+ private static final String X509DATA_ELEM_ = "X509Data";
+ private static final String X509SUBJNAME_ELEM_ = "X509SubjectName";
+ private static final String X509ISSUERSERIAL_ELEM_ = "X509IssuerSerial";
+ private static final String SERIAL_ELEM_ = "X509SerialNumber";
+ private static final String ISSUER_ELEM_ = "X509IssuerName";
+ private static final String QUALCERT_ELEM_ = "QualifiedCertificate";
+
+ private Element signerInfoElem_;
+
+ private String subjectNameItemSel_;
+ private String issuerNameItemSel_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public SignerInfoBean(Document slResponseDoc)
+ {
+ Element verifyXMLResponseElem = slResponseDoc.getDocumentElement();
+ signerInfoElem_ = DOMUtils.getChildElem(
+ verifyXMLResponseElem, Constants.NSURI_SL_11_, SIGNERINFO_ELEM_);
+
+ subjectNameItemSel_ = "2.5.4.3";
+ issuerNameItemSel_ = "2.5.4.3";
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void setSubjectNameItemSel(String selector)
+ {
+ subjectNameItemSel_ = selector;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getSubjectNameItem()
+ {
+ Element x509DataElem = DOMUtils.getChildElem(signerInfoElem_, Constants.NSURI_DSIG_, X509DATA_ELEM_);
+ String subjectNameStr = DOMUtils.getChildText(x509DataElem, Constants.NSURI_DSIG_, X509SUBJNAME_ELEM_);
+ if (subjectNameStr == null) return null;
+ return getRDN(subjectNameStr, subjectNameItemSel_);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getSerial()
+ {
+ Element x509DataElem = DOMUtils.getChildElem(signerInfoElem_, Constants.NSURI_DSIG_, X509DATA_ELEM_);
+ Element iSElem = DOMUtils.getChildElem(x509DataElem, Constants.NSURI_DSIG_, X509ISSUERSERIAL_ELEM_);
+ return DOMUtils.getChildText(iSElem, Constants.NSURI_DSIG_, SERIAL_ELEM_);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void setIssuerNameItemSel(String selector)
+ {
+ issuerNameItemSel_ = selector;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public String getIssuerNameItem()
+ {
+ Element x509DataElem = DOMUtils.getChildElem(signerInfoElem_, Constants.NSURI_DSIG_, X509DATA_ELEM_);
+ Element iSElem = DOMUtils.getChildElem(x509DataElem, Constants.NSURI_DSIG_, X509ISSUERSERIAL_ELEM_);
+ String issuerNameStr = DOMUtils.getChildText(iSElem, Constants.NSURI_DSIG_, ISSUER_ELEM_);
+ if (issuerNameStr == null) return null;
+ return getRDN(issuerNameStr, issuerNameItemSel_);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public boolean getIsQualified()
+ {
+ Element x509DataElem = DOMUtils.getChildElem(signerInfoElem_, Constants.NSURI_DSIG_, X509DATA_ELEM_);
+ Element qCElem = DOMUtils.getChildElem(x509DataElem, Constants.NSURI_SL_11_, QUALCERT_ELEM_);
+ return (qCElem != null);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private String getRDN(String nameStr, String oidStr)
+ {
+ try
+ {
+ RFC2253NameParser nameParser = new RFC2253NameParser(nameStr);
+ Name name = nameParser.parse();
+ ObjectID oid = ObjectID.getObjectID(oidStr);
+ if (oid == null) return null;
+ String[] rdns = name.getRDNs(oid);
+ if (rdns == null) return null;
+ StringBuffer rdnsStr = new StringBuffer();
+ for (int i = 0; i < rdns.length; i++)
+ {
+ if (i > 0) rdnsStr.append(", ");
+ rdnsStr.append(rdns[i]);
+ }
+ return rdnsStr.toString();
+ }
+ catch (RFC2253NameParserException e)
+ {
+ return null;
+ }
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java
new file mode 100644
index 000000000..a6652a56e
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java
@@ -0,0 +1,57 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayInputStream;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class RequestWrapper extends HttpServletRequestWrapper
+{
+
+ private ServletInputStream inputStream_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Generates a request wrapper around a particular request.
+ *
+ * @param request The request to be wrapped.
+ *
+ * @param inputStream The new inputstream, which will be returned by method {@link #getInputStream}, and
+ * whose length will be returned by method {@link #getContentLength}.
+ */
+ public RequestWrapper(HttpServletRequest request, ByteArrayInputStream inputStream)
+ {
+ super(request);
+ inputStream_ = new ServletInputStream(inputStream);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see #RequestWrapper(HttpServletRequest, ByteArrayInputStream)
+ */
+ public javax.servlet.ServletInputStream getInputStream()
+ {
+ return inputStream_;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see #RequestWrapper(HttpServletRequest, ByteArrayInputStream)
+ */
+ public int getContentLength()
+ {
+ return inputStream_.getContentLength();
+ }
+
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java
new file mode 100644
index 000000000..420723abb
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java
@@ -0,0 +1,44 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ResponseWrapper extends HttpServletResponseWrapper
+{
+ private ServletOutputStream outputStream_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public ResponseWrapper(HttpServletResponse response)
+ {
+ super(response);
+ outputStream_ = new ServletOutputStream();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public javax.servlet.ServletOutputStream getOutputStream()
+ {
+ return outputStream_;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Returns the wrapped response as a byte array.
+ *
+ * @return the response as a byte array.
+ */
+ public byte[] toByteArray()
+ {
+ return outputStream_.toByteArray();
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java
new file mode 100644
index 000000000..0ff14551f
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java
@@ -0,0 +1,381 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.fileupload.DiskFileUpload;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.xerces.parsers.DOMParser;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.beans.ChecksInfoBean;
+import at.gv.egovernment.moa.spss.slinterface.beans.DataInfoBean;
+import at.gv.egovernment.moa.spss.slinterface.beans.SignerInfoBean;
+import at.gv.egovernment.moa.spss.slinterface.moainvoker.MOAInvoker;
+import at.gv.egovernment.moa.spss.slinterface.servlets.SLRequest;
+import at.gv.egovernment.moa.spss.slinterface.transformers.MOA2SL;
+import at.gv.egovernment.moa.spss.slinterface.transformers.SL2MOA;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class SL2MOAFilter implements Filter
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_FILTERS_);
+
+ private FilterConfig config_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+ */
+ public void init(FilterConfig config) throws ServletException
+ {
+ // Store filter configuration
+ config_ = config;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
+ * javax.servlet.FilterChain)
+ */
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException
+ {
+ // It is necessary to set the content type header already here, because for any unknown reason setting
+ // it in the response JSP page has no effects at all. Perhaps any of the filters or the like already
+ // writes to the response output stream.
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+ httpResponse.setHeader("Content-Type", "text/html; charset='ISO-8859-1'");
+
+ // Create session
+ HttpSession session = ((HttpServletRequest) request).getSession(true);
+
+ // Check if request is HTTP-POST
+ checkHttpPost((HttpServletRequest) request);
+
+ // Remember remote IP address for later URL rewriting
+ session.setAttribute("remoteAddr", request.getRemoteAddr());
+
+ // Get SL request from content of request
+ SLRequest slRequest = parseRequest((HttpServletRequest) request);
+ session.setAttribute("slRequest", slRequest);
+
+ // Schema validate SL request
+ CharArrayReader slXmlRequestCAR = new CharArrayReader(slRequest.xmlRequest_.toCharArray());
+ Document slXMLRequestDoc = parseSlXmlRequest(slXmlRequestCAR);
+ logger_.debug("Finnished schema validating SL request.");
+
+ // Transform SL request into a MOA SPSS request
+ Properties initProps = (Properties)config_.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_);
+ String trustProfileId = initProps.getProperty(Constants.IP_SP_TRUSTPROFILEID_);
+ Document moaXMLRequestDoc = SL2MOA.toMoaVerifyXMLSignatureRequest(slXMLRequestDoc, trustProfileId);
+ ByteArrayOutputStream moaRequestBOS = new ByteArrayOutputStream();
+ MOAInvoker.serializeDocument(moaXMLRequestDoc, moaRequestBOS);
+ logger_.debug("SL request transformed into MOA request:\n" + moaRequestBOS);
+ ByteArrayInputStream moaRequestIS = new ByteArrayInputStream(moaRequestBOS.toByteArray());
+ logger_.debug("Finnished transforming SL request into a MOA SP request.");
+
+ // Invoke MOA SPSS
+ RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) request, moaRequestIS);
+ ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);
+ chain.doFilter(requestWrapper, responseWrapper);
+ logger_.debug("Finnished invoking MOA SP service.");
+
+ // Parse MOA response
+ DOMParser xmlParser = (DOMParser) config_.getServletContext().getAttribute(Constants.WSCP_XMLPARSER_);
+ ServletOutputStream moaResponseSOS = (ServletOutputStream) responseWrapper.getOutputStream();
+ ByteArrayInputStream moaResponseBIS = new ByteArrayInputStream(moaResponseSOS.toByteArray());
+ InputSource responseSource = new InputSource(moaResponseBIS);
+ Document moaResponseDoc;
+ try
+ {
+ xmlParser.parse(responseSource);
+ moaResponseDoc = xmlParser.getDocument();
+ }
+ catch (SAXException e)
+ {
+ String message = "Parsing MOA XML response failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ logger_.debug("Finnished parsing MOA SP response.");
+
+ // Create bean with info about signed data
+ try
+ {
+ DataInfoBean dataInfo = new DataInfoBean(
+ moaXMLRequestDoc,
+ moaResponseDoc,
+ ((HttpServletRequest) request).getContextPath(),
+ session,
+ config_.getServletContext());
+ session.setAttribute("dataInfo", dataInfo);
+ }
+ catch (Exception e)
+ {
+ String message = "Creating DataInfobean failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ logger_.debug("Finnished creating bean with info about signed data.");
+
+ // Transform MOA response into a SL response
+ Document slResponseDoc;
+ slResponseDoc = MOA2SL.toSlVerifyXMLSignatureResponse(moaResponseDoc);
+ session.setAttribute("slResponseDoc", slResponseDoc);
+ logger_.debug("Finnished transforming MOA SP response into a SL response.");
+
+ // Create bean with info about signer
+ SignerInfoBean signerInfo = new SignerInfoBean(slResponseDoc);
+ request.setAttribute("signerInfo", signerInfo);
+ logger_.debug("Finnished creating bean with info about signer.");
+
+ // Create bean with info about checks
+ ChecksInfoBean checksInfo = new ChecksInfoBean(slResponseDoc);
+ request.setAttribute("checksInfo", checksInfo);
+ logger_.debug("Finnished creating bean with info about checks.");
+
+ // Include jsp page, which writes the overview information about the verified signature
+ try
+ {
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/pages/resultOverview.jsp");
+ dispatcher.include(request, response);
+ }
+ catch (IOException e)
+ {
+ String message = "Failed to create result overview page.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ logger_.debug("Finnished SL2MOAFilter.");
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see javax.servlet.Filter#destroy()
+ */
+ public void destroy()
+ {
+ // Nothing to do here at the moment.
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ // TODO Revisit if method can be removed
+ /* private void initTransformer(ServletContext context, String initPropStylesheetLoc) throws ServletException
+ {
+ String stylesheetName =
+ (Constants.IP_SL2MOA_STYLESHEET_.equals(initPropStylesheetLoc))
+ ? "sl2Moa"
+ : "moa2Sl";
+
+ String contextAttrName =
+ (Constants.IP_SL2MOA_STYLESHEET_.equals(initPropStylesheetLoc))
+ ? Constants.WSCP_SL2MOA_TRANSFORMER_
+ : Constants.WSCP_MOA2SL_TRANSFORMER_;
+
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ Properties initProps = (Properties) context.getAttribute(Constants.WSCP_INIT_PROPS_);
+ String stylesheetLoc = initProps.getProperty(initPropStylesheetLoc);
+ InputStream stylesheetIS = context.getResourceAsStream(stylesheetLoc);
+ if (stylesheetIS == null)
+ {
+ String message =
+ "Cannot load " + stylesheetName + " stylesheet from location \"" + stylesheetLoc + "\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ Transformer transformer;
+ try
+ {
+ StreamSource stylesheetSS = new StreamSource(stylesheetIS);
+ transformer = transformerFactory.newTransformer(stylesheetSS);
+ }
+ catch (TransformerConfigurationException e)
+ {
+ String message = "Cannot create XSLT transformer with " + stylesheetName + " stylesheet.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ context.setAttribute(contextAttrName, transformer);
+ }*/
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Parses the http request.
+ */
+ private SLRequest parseRequest(HttpServletRequest request) throws IOException
+ {
+ SLRequest slRequest = new SLRequest();
+
+ // Check if request URL ends with "http-security-layer-request"
+ // @TODO Don't know if this check is sufficient - spec says request URL must have this value as path
+ String requestURI = request.getRequestURI();
+ if (!requestURI.endsWith(Constants.SLC_NAME_HTTP_REQUEST_))
+ {
+ String message = "Request does not end with \"" + Constants.SLC_NAME_HTTP_REQUEST_ + "\".";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ if (FileUpload.isMultipartContent(request))
+ {
+ // Request is encoded as mulitpart/form-data
+ List items;
+ try
+ {
+ DiskFileUpload upload = new DiskFileUpload();
+ items = upload.parseRequest(request);
+ }
+ catch (FileUploadException e)
+ {
+ String message = "Cannot parse multipart/form-data request.";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ Iterator itemsIt = items.iterator();
+ while (itemsIt.hasNext())
+ {
+ FileItem currItem = (FileItem) itemsIt.next();
+ String currItemName = currItem.getFieldName();
+ if (Constants.SLC_NAME_XML_REQUEST_.equals(currItemName))
+ slRequest.xmlRequest_ = currItem.getString();
+ else if (Constants.SLC_NAME_DATA_URL_.equals(currItemName))
+ slRequest.dataUrl_ = currItem.getString();
+ else if (Constants.SLC_NAME_STYLESHEET_URL_.equals(currItemName))
+ slRequest.stylesheetUrl_ = currItem.getString();
+ else if (Constants.SLC_NAME_REDIRECT_URL_.equals(currItemName))
+ slRequest.redirectUrl_ = currItem.getString();
+ else
+ continue; // @TODO Do not evaluate other params at the moment
+ }
+ }
+ else
+ {
+ // Request is encoded as application/x-www-form-urlencoded
+ Map paramsMap = request.getParameterMap();
+ Iterator paramNames = paramsMap.keySet().iterator();
+ while (paramNames.hasNext())
+ {
+ String currName = (String) paramNames.next();
+ String[] currValues = (String[]) paramsMap.get(currName);
+ if (Constants.SLC_NAME_XML_REQUEST_.equals(currName))
+ slRequest.xmlRequest_ = currValues[0];
+ else if (Constants.SLC_NAME_DATA_URL_.equals(currName))
+ slRequest.dataUrl_ = currValues[0];
+ else if (Constants.SLC_NAME_STYLESHEET_URL_.equals(currName))
+ slRequest.stylesheetUrl_ = currValues[0];
+ else if (Constants.SLC_NAME_REDIRECT_URL_.equals(currName))
+ slRequest.redirectUrl_ = currValues[0];
+ else
+ continue; // @TODO Do not evaluate other params at the moment
+ }
+ }
+
+ if (slRequest.xmlRequest_ == null || slRequest.dataUrl_ == null ||
+ slRequest.stylesheetUrl_ != null || slRequest.redirectUrl_ != null)
+ {
+ // @TODO Only combination of XMLRequest and DataURL allowed at the moment
+ String message = "Currently only (XMLRequest + DataURL) is supported.";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ return slRequest;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private Document parseSlXmlRequest(Reader slXmlRequest) throws ServletException
+ {
+ // Parse sl request
+ InputSource slXMLRequestIS = new InputSource(slXmlRequest);
+ Document slXmlRequestDoc = null;
+ try
+ {
+ DOMParser xmlParser = (DOMParser) config_.getServletContext().getAttribute(Constants.WSCP_XMLPARSER_);
+ xmlParser.parse(slXMLRequestIS);
+ slXmlRequestDoc = xmlParser.getDocument();
+ }
+ catch (Exception e)
+ {
+ String message = "Parsing Security-Layer request failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ if (logger_.getEffectiveLevel().isGreaterOrEqual(Level.DEBUG))
+ {
+ ByteArrayOutputStream debugOutputStream = new ByteArrayOutputStream();
+ try
+ {
+ MOAInvoker.serializeDocument(slXmlRequestDoc, debugOutputStream);
+ logger_.debug("XML-Request received:\n" + debugOutputStream);
+ }
+ catch (IOException e)
+ {
+ // No debug output if this fails
+ }
+ }
+
+ // Check if namespace is correct
+ String namespaceURI = slXmlRequestDoc.getDocumentElement().getNamespaceURI();
+ if (!Constants.NSURI_SL_11_.equals(namespaceURI) && !Constants.NSURI_SL_12_.equals(namespaceURI))
+ {
+ String message = "XML request has invalid namespace: \"" + namespaceURI + "\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+
+ return slXmlRequestDoc;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private void checkHttpPost(HttpServletRequest request) throws ServletException
+ {
+ String method = request.getMethod();
+ if (!"POST".equals(method))
+ {
+ String message = "HTTP method \"" + method + "\" not supported. Must be \"POST\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java
new file mode 100644
index 000000000..b0609c2f8
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java
@@ -0,0 +1,55 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ServletInputStream extends javax.servlet.ServletInputStream
+{
+ private ByteArrayInputStream inputStream_;
+ private int length_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Generates a new <code>ServletInputStram</code> from the specified stream.
+ *
+ * @param inputStream See above.
+ */
+ public ServletInputStream(ByteArrayInputStream inputStream)
+ {
+ super();
+ inputStream_ = inputStream;
+ length_ = inputStream_.available();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Reads a single byte from the underlying <code>ByteArrayInputStream</code>.
+ *
+ * @see java.io.InputStream#read()
+ */
+ public int read() throws IOException
+ {
+ return inputStream_.read();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the length of the content from this input stream. This equals to the number of bytes which where
+ * available at the time of creating this <code>ServletInputStream</code>.
+ */
+ public int getContentLength()
+ {
+ return length_;
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java
new file mode 100644
index 000000000..b790ee55c
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java
@@ -0,0 +1,50 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ServletOutputStream extends javax.servlet.ServletOutputStream
+{
+ private ByteArrayOutputStream outputStream_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Default constructor.
+ */
+ public ServletOutputStream()
+ {
+ super();
+ outputStream_ = new ByteArrayOutputStream();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see java.io.OutputStream#write(int)
+ */
+ public void write(int b) throws IOException
+ {
+ outputStream_.write(b);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Returns the content of this stream as a byte array.
+ *
+ * @return the content of this stream as a byte array.
+ */
+ public byte[] toByteArray()
+ {
+ return outputStream_.toByteArray();
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java
new file mode 100644
index 000000000..8b8befb1c
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java
@@ -0,0 +1,214 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.listeners;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.log4j.Logger;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.parsers.XMLGrammarPreparser;
+import org.apache.xerces.util.SymbolTable;
+import org.apache.xerces.util.XMLGrammarPoolImpl;
+import org.apache.xerces.xni.grammars.XMLGrammarDescription;
+import org.apache.xerces.xni.grammars.XMLGrammarPool;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.xml.sax.SAXException;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.URLRewriter;
+import at.gv.egovernment.moa.spss.slinterface.beans.InitPropertiesBean;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ContextListener implements ServletContextListener
+{
+ private static final String SAX_NAMESPACES_FEATURE = "http://xml.org/sax/features/namespaces";
+ private static final String SAX_VALIDATION_FEATURE = "http://xml.org/sax/features/validation";
+
+ private static final String XERCES_SCHEMA_VALIDATION_FEATURE =
+ "http://apache.org/xml/features/validation/schema";
+ private static final String XERCES_NORMALIZED_VALUE_FEATURE =
+ "http://apache.org/xml/features/validation/schema/normalized-value";
+ private static final String XERCES_INCLUDE_IGNORABLE_WHITESPACE_FEATURE =
+ "http://apache.org/xml/features/dom/include-ignorable-whitespace";
+ private static final String XERCES_CREATE_ENTITY_REF_NODES_FEATURE =
+ "http://apache.org/xml/features/dom/create-entity-ref-nodes";
+ protected static final String XERCES_DEFER_NODE_EXPANSION_ =
+ "http://apache.org/xml/features/dom/defer-node-expansion";
+ protected static final String XERCES_AUGMENT_PSI_ =
+ "http://apache.org/xml/features/validation/schema/augment-psvi";
+
+ private static final int BIG_PRIME = 2039;
+
+ private static Logger logger_ = Logger.getLogger(Constants.LH_LISTENERS_);
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Initializes the web application.
+ * @throws Exception
+ *
+ * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
+ */
+ public void contextInitialized(ServletContextEvent event)
+ {
+ logger_.debug("Context is being initialized.");
+
+ ServletContext context = event.getServletContext();
+
+ String initPropsLoc = System.getProperty(Constants.SP_INIT_PROPS_LOC_);
+ if (initPropsLoc == null)
+ {
+ logger_.fatal("System property \"" + Constants.SP_INIT_PROPS_LOC_ + "\" not set.");
+ logger_.fatal("Web application initialization failed.");
+ return;
+ }
+
+ // Load init properties
+ try
+ {
+ logger_.debug("Init properties location \"" + initPropsLoc + "\" will be used.");
+
+ // Try to interpret init properties location as relative to the web application root
+ InputStream initPropsIS = context.getResourceAsStream(initPropsLoc);
+
+ if (initPropsIS == null)
+ {
+ // If this does not work, try to interpret init properties location as an absolute file system path
+ initPropsIS = new FileInputStream(initPropsLoc);
+ }
+
+ Properties initProps = new Properties();
+ initProps.load(initPropsIS);
+ context.setAttribute(Constants.WSCP_INIT_PROPS_, initProps);
+
+ // Prepare application bean knowing about init properties
+ InitPropertiesBean initPropsBean = new InitPropertiesBean(initProps);
+ context.setAttribute(Constants.WSCP_INITPROPS_BEAN_, initPropsBean);
+ }
+ catch (IOException e)
+ {
+ logger_.fatal("Cannot load initialization properties from location \"" + initPropsLoc + "\".", e);
+ logger_.fatal("Web application initialization failed.");
+ return;
+ }
+
+ // Put helper object for rewriting URLs in the result page into the context
+ URLRewriter urlRewriter = new URLRewriter((Properties)context.getAttribute(Constants.WSCP_INIT_PROPS_));
+ context.setAttribute(Constants.WSCP_URL_REWRITER_, urlRewriter);
+
+ // Initialize XML parser
+ SymbolTable symbolTable = new SymbolTable(BIG_PRIME);
+ XMLGrammarPool grammarPool = new XMLGrammarPoolImpl();
+
+ XMLGrammarPreparser preparser = new XMLGrammarPreparser(symbolTable);
+ preparser.registerPreparser(XMLGrammarDescription.XML_SCHEMA, null);
+ preparser.setProperty(org.apache.xerces.impl.Constants.XERCES_PROPERTY_PREFIX
+ + org.apache.xerces.impl.Constants.XMLGRAMMAR_POOL_PROPERTY, grammarPool);
+ preparser.setFeature(SAX_NAMESPACES_FEATURE, true);
+ preparser.setFeature(SAX_VALIDATION_FEATURE, true);
+
+ // Schema for Security-Layer 1.2 alpha (including LocRefContent)
+ Properties initProps = (Properties) context.getAttribute(Constants.WSCP_INIT_PROPS_);
+ String slSchemaLoc = initProps.getProperty(Constants.IP_SL_SCHEMA_);
+ if (!preparseSchema(context, preparser, slSchemaLoc))
+ {
+ logger_.fatal("Web application initialization failed.");
+ return;
+ }
+
+ // Schema for MOA 1.2
+ String moaSchemaLoc = initProps.getProperty(Constants.IP_MOA_SCHEMA_);
+ if (!preparseSchema(context, preparser, moaSchemaLoc))
+ {
+ logger_.fatal("Web application initialization failed.");
+ return;
+ }
+
+ // Schema for SLXHTML 1.0
+ String slxhtmlSchemaLoc = initProps.getProperty(Constants.IP_SLXHTML_SCHEMA_);
+ if (!preparseSchema(context, preparser, slxhtmlSchemaLoc))
+ {
+ logger_.fatal("Web application initialization failed.");
+ return;
+ }
+
+
+ // TODO parser is not threadsafe
+ DOMParser xmlParser = new DOMParser(symbolTable, grammarPool);
+ try
+ {
+ xmlParser.setFeature(SAX_NAMESPACES_FEATURE, true);
+ xmlParser.setFeature(SAX_VALIDATION_FEATURE, true);
+ xmlParser.setFeature(XERCES_SCHEMA_VALIDATION_FEATURE, true);
+ xmlParser.setFeature(XERCES_NORMALIZED_VALUE_FEATURE, false);
+ xmlParser.setFeature(XERCES_INCLUDE_IGNORABLE_WHITESPACE_FEATURE, true);
+ xmlParser.setFeature(XERCES_CREATE_ENTITY_REF_NODES_FEATURE, false);
+ xmlParser.setFeature(XERCES_DEFER_NODE_EXPANSION_, true);
+ xmlParser.setFeature(XERCES_AUGMENT_PSI_, false);
+ xmlParser.setErrorHandler(new XMLParserErrorHandler(false, true, true));
+ }
+ catch (SAXException e)
+ {
+ String message = "Initialization of XML parser failed.";
+ logger_.fatal(message, e);
+ logger_.fatal("Web application initialization failed.");
+ return;
+ }
+ context.setAttribute(Constants.WSCP_XMLPARSER_, xmlParser);
+
+ String message = "Web application initialization succeeded.";
+ logger_.info(message);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Does some clean up at finalization of the web application.
+ *
+ * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
+ */
+ public void contextDestroyed(ServletContextEvent event)
+ {
+ // Remove init properties from web service context
+ Properties initProps = (Properties) event.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_);
+ if (initProps != null) event.getServletContext().removeAttribute(Constants.WSCP_INIT_PROPS_);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private boolean preparseSchema(ServletContext context, XMLGrammarPreparser preparser, String schemaLoc)
+ {
+ InputStream schemaIS = context.getResourceAsStream(schemaLoc);
+ if (schemaIS == null)
+ {
+ String message = "Cannot load schema from location \"" + schemaLoc + "\".";
+ logger_.fatal(message);
+ return false;
+ }
+ try
+ {
+ String schemaSystemId = context.getResource(schemaLoc).toExternalForm();
+ preparser.preparseGrammar(XMLGrammarDescription.XML_SCHEMA,
+ new XMLInputSource(null, schemaSystemId, null, schemaIS, null));
+ }
+ catch (Exception e)
+ {
+ String message = "Parsing schema loaded from location \"" + schemaLoc + "\" failed.";
+ logger_.fatal(message, e);
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/listeners/XMLParserErrorHandler.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/listeners/XMLParserErrorHandler.java
new file mode 100644
index 000000000..496d0aadb
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/listeners/XMLParserErrorHandler.java
@@ -0,0 +1,65 @@
+/*
+ * Created on 02.12.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.listeners;
+
+import org.apache.log4j.Logger;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class XMLParserErrorHandler implements ErrorHandler
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_LISTENERS_XMLPARSER_);
+
+ private boolean reportWarning_, reportError_, reportFatal_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public XMLParserErrorHandler(boolean reportWarning, boolean reportError, boolean reportFatal)
+ {
+ reportWarning_ = reportWarning;
+ reportError_ = reportError;
+ reportFatal_ = reportFatal;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
+ */
+ public void warning(SAXParseException exception) throws SAXException
+ {
+ logger_.warn("XML parser reported a warning.", exception);
+ if (reportWarning_) throw exception;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
+ */
+ public void error(SAXParseException exception) throws SAXException
+ {
+ logger_.error("XML parser reported an error.", exception);
+ if (reportError_) throw exception;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
+ */
+ public void fatalError(SAXParseException exception) throws SAXException
+ {
+ logger_.error("XML parser reported a fatal error.", exception);
+ if (reportFatal_) throw exception;
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/moainvoker/MOAInvoker.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/moainvoker/MOAInvoker.java
new file mode 100644
index 000000000..e89d255f0
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/moainvoker/MOAInvoker.java
@@ -0,0 +1,92 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.moainvoker;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.rmi.RemoteException;
+import java.util.Vector;
+
+import javax.xml.namespace.QName;
+import javax.xml.rpc.Call;
+import javax.xml.rpc.Service;
+import javax.xml.rpc.ServiceException;
+import javax.xml.rpc.ServiceFactory;
+
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+import org.w3c.dom.Document;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class MOAInvoker
+{
+ /**
+ * Invokes MOA SP.
+ *
+ * @param request The XML request to be sent to MOA SP.
+ *
+ * @param endpoint The endpoint of the SOAP service where to send the XML request to.
+ *
+ * @return the XML response from the service.
+ *
+ * @throws Exception if getting the XML response from the SOAP response body fails.
+ *
+ * @throws RemoteException if MOA SP signals an error.
+ *
+ * @throws ServiceException if the SOAP client invoking MOA SP signals an error.
+ */
+ public static Document invokeSP(Document request, String endpoint)
+ throws Exception, RemoteException, ServiceException
+ {
+ QName serviceQName = new QName(Constants.MI_SP_QNAME_);
+ return invoke(request, endpoint, serviceQName);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private static Document invoke(Document request, String endpoint, QName serviceQName) throws Exception
+ {
+ // Instantiate AXIS service
+ Service service = ServiceFactory.newInstance().createService(serviceQName);
+
+ // Create and configure service call
+ Call call = service.createCall();
+ call.setTargetEndpointAddress(endpoint);
+
+ // Create SOAP body
+ SOAPBodyElement body = new SOAPBodyElement(request.getDocumentElement());
+ SOAPBodyElement[] params = new SOAPBodyElement[] {body};
+
+ // Make call
+ Vector responses = (Vector) call.invoke(params);
+
+ // Get response
+ SOAPBodyElement responseBody = (SOAPBodyElement) responses.get(0);
+ Document response = responseBody.getAsDocument();
+ return response;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static void serializeDocument(Document doc, OutputStream out) throws IOException
+ {
+ OutputFormat format = new OutputFormat(doc);
+
+ format.setLineSeparator("\n");
+ format.setIndenting(false);
+ format.setPreserveSpace(true);
+ format.setOmitXMLDeclaration(false);
+ format.setEncoding("UTF-8");
+
+ XMLSerializer serializer = new XMLSerializer(out, format);
+ serializer.serialize(doc);
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/HashInputDataServlet.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/HashInputDataServlet.java
new file mode 100644
index 000000000..f7cfb7e6c
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/HashInputDataServlet.java
@@ -0,0 +1,93 @@
+/*
+ * Created on 01.12.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.servlets;
+
+import java.io.FileInputStream;
+import java.io.OutputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.log4j.Logger;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.Utils;
+import at.gv.egovernment.moa.spss.slinterface.beans.DataInfoBean;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class HashInputDataServlet extends HttpServlet
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_SERVLETS_);
+
+ /**
+ * Default constructor.
+ */
+ public HashInputDataServlet()
+ {
+ super();
+ }
+
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException
+ {
+ // Get DataInfoBean object from session
+ HttpSession session = request.getSession(false);
+ if (session == null)
+ {
+ String message = "No session available.";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ DataInfoBean dataInfo = (DataInfoBean) session.getAttribute("dataInfo");
+
+ // Get parameter inicating which hash input data file to show
+ String hidCountStr = request.getParameter("hidCount");
+ if (hidCountStr == null)
+ {
+ String message = "Parameter \"hidCount\" not available in request.";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ int hidCount = -1;
+ try
+ {
+ hidCount = Integer.parseInt(hidCountStr);
+ }
+ catch (NumberFormatException e)
+ {
+ String message = "Parameter \"hidCount\" (\"" + hidCount + "\") is not a valid string representation of an integer.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+
+ // Get file name of temporary HID file
+ dataInfo.setHashInputDataCount(hidCount);
+ String hidFilename = dataInfo.getHashInputDataFilename();
+
+ // Set content type
+ boolean isSLXHTML = dataInfo.getIsSLXHTMLDocument();
+ String contenType = (isSLXHTML) ? "text/html" : "application/octet-stream";
+ response.setContentType(contenType);
+
+ // Write content from temporary HID file to response OS
+ try
+ {
+ FileInputStream hidFIS = new FileInputStream(hidFilename);
+ OutputStream responseOS = response.getOutputStream();
+ Utils.transferStreams(hidFIS, responseOS);
+ }
+ catch (Exception e)
+ {
+ String message = "Writing hash input data to response stream failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/MOAServlet.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/MOAServlet.java
new file mode 100644
index 000000000..362793064
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/MOAServlet.java
@@ -0,0 +1,113 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.servlets;
+
+import java.io.IOException;
+import java.rmi.RemoteException;
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.rpc.ServiceException;
+
+import org.apache.log4j.Logger;
+import org.apache.xerces.parsers.DOMParser;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.moainvoker.MOAInvoker;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class MOAServlet extends HttpServlet
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_SERVLETS_);
+
+ /**
+ * Default constructor.
+ */
+ public MOAServlet()
+ {
+ super();
+ }
+
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException
+ {
+ // Get moa request form http request
+ Document moaXmlRequest = null;
+ DOMParser xmlParser = (DOMParser) this.getServletContext().getAttribute(Constants.WSCP_XMLPARSER_);
+ try
+ {
+ InputSource requestIS = new InputSource(request.getInputStream());
+ xmlParser.parse(requestIS);
+ moaXmlRequest = xmlParser.getDocument();
+ }
+ catch (IOException ioe)
+ {
+ String message = "Getting MOA XML request from http request input failed.";
+ logger_.error(message, ioe);
+ throw new ServletException(message, ioe);
+ }
+ catch (SAXException se)
+ {
+ String message = "Parsing MOA XML request got from http request failed.";
+ logger_.error(message, se);
+ throw new ServletException(message, se);
+ }
+
+ // Send request to MOA SP
+ Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_);
+ String endPoint = initProps.getProperty(Constants.IP_SP_ENDPOINT_);
+ if (endPoint == null)
+ {
+ String message = "No endpoint configured for MOA SP service.";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ Document moaXMLResponseDoc = null;
+ try
+ {
+ moaXMLResponseDoc = MOAInvoker.invokeSP(moaXmlRequest, endPoint);
+ }
+ catch (Exception e)
+ {
+ String message;
+ if (e instanceof RemoteException)
+ {
+ message = "MOA SP service indicated an error at request execution.";
+ }
+ else if (e instanceof ServiceException)
+ {
+ message = "MOA SP client indicated an error at request execution.";
+ }
+ else
+ {
+ message = "Could not create DOM Document from MOA SP service response.";
+ }
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ logger_.debug("Got response from MOA SP service.");
+
+ // Write moa response to http response
+ try
+ {
+ MOAInvoker.serializeDocument(moaXMLResponseDoc, response.getOutputStream());
+ }
+ catch (IOException e)
+ {
+ String message = "Writing MOA SP XML response to http response failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ logger_.debug("Wrote response from MOA SP service to http response outputstream.");
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/ReturnServlet.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/ReturnServlet.java
new file mode 100644
index 000000000..84ce26be0
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/ReturnServlet.java
@@ -0,0 +1,129 @@
+/*
+ * Created on 25.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.servlets;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.Utils;
+import at.gv.egovernment.moa.spss.slinterface.moainvoker.MOAInvoker;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ReturnServlet extends HttpServlet
+{
+
+ private static Logger logger_ = Logger.getLogger(Constants.LH_SERVLETS_);
+
+ /**
+ * Default constructor.
+ */
+ public ReturnServlet()
+ {
+ super();
+ }
+
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException
+ {
+ // Get session
+ HttpSession session = request.getSession(false);
+ if (session == null)
+ {
+ String message = "No session available.";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+
+ // Get original SL request from session
+ SLRequest slRequest = (SLRequest) session.getAttribute("slRequest");
+ if (slRequest == null)
+ {
+ String message = "Session object \"slRequest\" not available.";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+
+ // Get SL response from session
+ Document slResponseDoc = (Document) session.getAttribute("slResponseDoc");
+ if (slResponseDoc == null)
+ {
+ String message = "Session object \"slResponseDoc\" not available.";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+
+ URLConnection dataURLConn;
+ try
+ {
+ // TODO Does not conform to SL/Bindings/sec. 3.3.2.2
+
+ // Open connection to DataURL
+ URL dataURL = new URL(slRequest.dataUrl_);
+ dataURLConn = dataURL.openConnection();
+ dataURLConn.setDoOutput(true);
+ OutputStream dataURLOS = dataURLConn.getOutputStream();
+ MOAInvoker.serializeDocument(slResponseDoc, dataURLOS);
+ dataURLOS.flush();
+ }
+ catch (Exception e)
+ {
+ String message = "Sending SL XML response to DataURL failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+
+ // Forward response from DataURL to client
+ forwardResponse(dataURLConn, response);
+
+ session.invalidate();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private void forwardResponse(URLConnection dataURLConn, ServletResponse response) throws ServletException
+ {
+ // TODO Does not conform to SL/Bindings/sec. 3.3.2.1
+
+ // Make sure that content type of DataURL response is text/html
+ String dataURLContentType = dataURLConn.getContentType();
+ if (dataURLContentType == null || !dataURLContentType.startsWith("text/html"))
+ {
+ String message = "Unsupported content type of DataURL response: \"" + dataURLContentType + "\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+
+ try
+ {
+ InputStream dataURLIS = dataURLConn.getInputStream();
+ byte[] dataURLResponse = Utils.readFromInputStream(dataURLIS);
+ response.setContentType("text/html");
+ OutputStream responseOS = response.getOutputStream();
+ responseOS.write(dataURLResponse);
+ responseOS.flush();
+ }
+ catch (Exception e)
+ {
+ String message = "Forwarding DataURL response to client failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/SLRequest.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/SLRequest.java
new file mode 100644
index 000000000..3c19d5ff6
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/servlets/SLRequest.java
@@ -0,0 +1,19 @@
+/*
+ * Created on 25.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.servlets;
+
+/**
+ * Helper class, representing the fields of a Security-Layer request.
+ *
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class SLRequest
+{
+ public String xmlRequest_;
+ public String dataUrl_;
+ public String stylesheetUrl_;
+ public String redirectUrl_;
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/MOA2SL.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/MOA2SL.java
new file mode 100644
index 000000000..2e82d4d32
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/MOA2SL.java
@@ -0,0 +1,93 @@
+/*
+ * Created on 20.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.transformers;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+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.spss.slinterface.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class MOA2SL
+{
+ /**
+ * Transforms an MOA VerifyXMLSignatureResponse into a SL VerifyXMLSignatureResponse.
+ *
+ * @param moaVerifyXMLSignatureResponse The MOA VerifyXMLSignatureResponse to be transformed.
+ *
+ * @return the specified response document, transformed into a SL VerifyXMLSignatureResponse. Please note
+ * that <code>moaVerifyXMLSignatureResponse</code> is modified into the sl response.
+ *
+ * @pre moaVerifyXMLSignatureResponse is a valid instance of the SL Schema (version 1.2 or 1.1).
+ */
+ public static Document toSlVerifyXMLSignatureResponse(Document moaVerifyXMLSignatureResponse)
+ {
+ // Namespace to namespace prefix mapping
+ HashMap prefixMap = new HashMap(4);
+ prefixMap.put(Constants.NSURI_SL_10_, Constants.NSPRE_SL_10_);
+ prefixMap.put(Constants.NSURI_SL_11_, Constants.NSPRE_SL_11_);
+ prefixMap.put(Constants.NSURI_SL_12_, Constants.NSPRE_SL_12_);
+ prefixMap.put(Constants.NSURI_MOA_12_, Constants.NSPRE_MOA_12_);
+
+ // Namespaces to be changed
+ HashMap nsTransforms = new HashMap();
+ nsTransforms.put(Constants.NSURI_MOA_12_, Constants.NSURI_SL_11_);
+
+ // Names to be changed
+ HashMap nameTransforms = new HashMap();
+ nameTransforms.put(
+ new QName(Constants.NSURI_MOA_12_, "PublicAuthority"),
+ new QName(Constants.NSURI_MOA_12_,"PublicAuthority"));
+
+ Element verifyResponseElem = moaVerifyXMLSignatureResponse.getDocumentElement();
+ verifyResponseElem.setAttributeNS(Constants.NSURI_NAMESPACES_,
+ "xmlns:" + Constants.NSPRE_SL_10_, Constants.NSURI_SL_10_);
+ verifyResponseElem.setAttributeNS(Constants.NSURI_NAMESPACES_,
+ "xmlns:" + Constants.NSPRE_SL_11_, Constants.NSURI_SL_11_);
+
+ // Convert SL request into MOA request
+ verifyResponseElem =
+ Utils.transformDeep(verifyResponseElem, prefixMap, nsTransforms, nameTransforms);
+
+ // Add SignatureManifestCheck element (Code = 98)
+ Element signatureMFCheckElem = moaVerifyXMLSignatureResponse.createElementNS(
+ Constants.NSURI_SL_11_, Constants.NSPRE_SL_11_ + ":SignatureManifestCheck");
+ Element smfCodeElem = moaVerifyXMLSignatureResponse.createElementNS(
+ Constants.NSURI_SL_11_, Constants.NSPRE_SL_11_ + ":Code");
+ signatureMFCheckElem.appendChild(smfCodeElem);
+ smfCodeElem.appendChild(moaVerifyXMLSignatureResponse.createTextNode("98"));
+ Element signatureCheckElem = (Element) verifyResponseElem.getElementsByTagNameNS(
+ Constants.NSURI_SL_11_, "SignatureCheck").item(0);
+ verifyResponseElem.insertBefore(signatureMFCheckElem, signatureCheckElem.getNextSibling());
+
+ // Siblings of Certificate check must be in sl10 namespace
+ nsTransforms.clear();
+ nsTransforms.put(Constants.NSURI_SL_11_, Constants.NSURI_SL_10_);
+ nameTransforms.clear();
+ Element certCheckElem = (Element) verifyResponseElem.getElementsByTagNameNS(
+ Constants.NSURI_SL_11_, "CertificateCheck").item(0);
+ NodeList certCheckChildren = certCheckElem.getChildNodes();
+ ArrayList certCheckChildElemsList = new ArrayList(certCheckChildren.getLength());
+ for (int i = 0; i < certCheckChildren.getLength(); i++)
+ {
+ Node currentNode = certCheckChildren.item(i);
+ if (currentNode.getNodeType() == Node.ELEMENT_NODE)
+ certCheckChildElemsList.add(certCheckChildren.item(i));
+ }
+ for (int i = 0; i < certCheckChildElemsList.size(); i++)
+ Utils.transformDeep((Element) certCheckChildElemsList.get(i), prefixMap, nsTransforms,
+ nameTransforms);
+
+ return moaVerifyXMLSignatureResponse;
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/QName.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/QName.java
new file mode 100644
index 000000000..6da0c433f
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/QName.java
@@ -0,0 +1,51 @@
+/*
+ * Created on 20.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.transformers;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class QName
+{
+ public String nsUrl_;
+ public String localName_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public QName(String nsUrl, String localName)
+ {
+ nsUrl_ = nsUrl;
+ localName_ = localName;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public boolean equals(Object o)
+ {
+ if (o == null) return false;
+ if (o instanceof QName)
+ {
+ QName toBeCompared = (QName) o;
+
+ boolean nsURLEquals = (nsUrl_ == null)
+ ? toBeCompared.nsUrl_ == null
+ : nsUrl_.equals(toBeCompared.nsUrl_);
+ boolean localNameEquals = (localName_ == null)
+ ? toBeCompared.localName_ == null
+ : localName_.equals(toBeCompared.localName_);
+
+ return nsURLEquals && localNameEquals;
+ }
+ return false;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public int hashCode()
+ {
+ return new String(nsUrl_ + localName_).hashCode();
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/SL2MOA.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/SL2MOA.java
new file mode 100644
index 000000000..6c476e9ce
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/SL2MOA.java
@@ -0,0 +1,93 @@
+/*
+ * Created on 20.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.transformers;
+
+import java.util.HashMap;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class SL2MOA
+{
+ /**
+ * Transforms an SL VerifyXMLSignatureRequest into a MOA VerifyXMLSignatureRequest.
+ *
+ * @param slVerifyXMLSignatureRequest The SL VerifyXMLSignatureRequest to be transformed.
+ *
+ * @return the specified request document, transformed into a MOA VerifyXMLSignatureRequest. Please note
+ * that <code>slVerifyXMLSignatureRequest</code> is modified into the moa request.
+ *
+ * @pre slVerifyXMLSignatureRequest is a valid instance of the SL Schema (version 1.2 or 1.1).
+ */
+ public static Document toMoaVerifyXMLSignatureRequest(Document slVerifyXMLSignatureRequest,
+ String trustProfileID)
+ {
+ // Namespace to namespace prefix mapping
+ HashMap prefixMap = new HashMap(4);
+ prefixMap.put(Constants.NSURI_SL_10_, Constants.NSPRE_SL_10_);
+ prefixMap.put(Constants.NSURI_SL_11_, Constants.NSPRE_SL_11_);
+ prefixMap.put(Constants.NSURI_SL_12_, Constants.NSPRE_SL_12_);
+ prefixMap.put(Constants.NSURI_MOA_12_, Constants.NSPRE_MOA_12_);
+
+ // Namespaces to be changed
+ HashMap nsTransforms = new HashMap();
+ nsTransforms.put(Constants.NSURI_SL_10_, Constants.NSURI_MOA_12_);
+ nsTransforms.put(Constants.NSURI_SL_11_, Constants.NSURI_MOA_12_);
+ nsTransforms.put(Constants.NSURI_SL_12_, Constants.NSURI_MOA_12_);
+
+ // Names to be changed
+ HashMap nameTransforms = new HashMap();
+ nameTransforms.put(
+ new QName(Constants.NSURI_SL_11_, "SignatureInfo"),
+ new QName(Constants.NSURI_MOA_12_,"VerifySignatureInfo"));
+ nameTransforms.put(
+ new QName(Constants.NSURI_SL_12_, "SignatureInfo"),
+ new QName(Constants.NSURI_MOA_12_,"VerifySignatureInfo"));
+ nameTransforms.put(
+ new QName(Constants.NSURI_SL_11_, "SignatureEnvironment"),
+ new QName(Constants.NSURI_MOA_12_,"VerifySignatureEnvironment"));
+ nameTransforms.put(
+ new QName(Constants.NSURI_SL_12_, "SignatureEnvironment"),
+ new QName(Constants.NSURI_MOA_12_,"VerifySignatureEnvironment"));
+ nameTransforms.put(
+ new QName(Constants.NSURI_SL_11_, "SignatureLocation"),
+ new QName(Constants.NSURI_MOA_12_,"VerifySignatureLocation"));
+ nameTransforms.put(
+ new QName(Constants.NSURI_SL_12_, "SignatureLocation"),
+ new QName(Constants.NSURI_MOA_12_,"VerifySignatureLocation"));
+ nameTransforms.put(
+ new QName(Constants.NSURI_SL_11_, "Supplement"),
+ new QName(Constants.NSURI_MOA_12_,"SupplementProfile"));
+ nameTransforms.put(
+ new QName(Constants.NSURI_SL_12_, "Supplement"),
+ new QName(Constants.NSURI_MOA_12_,"SupplementProfile"));
+
+ Element verifyRequestElem = slVerifyXMLSignatureRequest.getDocumentElement();
+ verifyRequestElem.setAttributeNS(Constants.NSURI_NAMESPACES_,
+ "xmlns:" + Constants.NSPRE_MOA_12_, Constants.NSURI_MOA_12_);
+
+ // Convert SL request into MOA request
+ verifyRequestElem = Utils.transformDeep(verifyRequestElem, prefixMap, nsTransforms, nameTransforms);
+
+ // Add ReturnHashInputData element
+ Element returnHashInputDataElem = slVerifyXMLSignatureRequest.createElementNS(
+ Constants.NSURI_MOA_12_, Constants.NSPRE_MOA_12_ + ":ReturnHashInputData");
+ verifyRequestElem.appendChild(returnHashInputDataElem);
+
+ // Add trust profile ID element
+ Element trustProfileIDElem = slVerifyXMLSignatureRequest.createElementNS(
+ Constants.NSURI_MOA_12_, Constants.NSPRE_MOA_12_ + ":TrustProfileID");
+ trustProfileIDElem.appendChild(slVerifyXMLSignatureRequest.createTextNode(trustProfileID));
+ verifyRequestElem.appendChild(trustProfileIDElem);
+
+ return slVerifyXMLSignatureRequest;
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/Utils.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/Utils.java
new file mode 100644
index 000000000..d03895efe
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/Utils.java
@@ -0,0 +1,129 @@
+/*
+ * Created on 20.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.transformers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.xerces.dom.DocumentImpl;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.DocumentTraversal;
+import org.w3c.dom.traversal.NodeFilter;
+import org.w3c.dom.traversal.NodeIterator;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class Utils
+{
+ /**
+ *
+ * @param elem
+ * @param prefixes
+ * @param namespaces
+ * @param names
+ *
+ * @pre <code>elem</code> is backed by a <code>org.apache.xerces.dom.DocumentImpl</code>.
+ */
+ public static Element transformDeep(Element elem, Map prefixes, Map namespaces, Map names)
+ {
+ // Get node iterator for element
+ DocumentTraversal docTraversal = (DocumentImpl) elem.getOwnerDocument();
+ NodeIterator elemsIt = docTraversal.createNodeIterator(elem, NodeFilter.SHOW_ELEMENT, null, true);
+
+ // Make iterator immutable
+ List elemsList = new LinkedList();
+ while (true)
+ {
+ Node currNode = elemsIt.nextNode();
+ if (currNode == null) break;
+ elemsList.add(currNode);
+ }
+
+ Iterator elemsImmIt = elemsList.iterator();
+ Element returnValue = null;
+ while (elemsImmIt.hasNext())
+ {
+ Element currElem = (Element) elemsImmIt.next();
+
+ String nsUri = currElem.getNamespaceURI();
+ String localName = currElem.getLocalName();
+ QName qName = new QName(nsUri, localName);
+
+ // Check if element is in "names"
+ QName newQName = (QName)names.get(qName);
+ if (newQName != null)
+ {
+ Element transformedElem = transformElem(currElem, newQName, prefixes);
+ if (returnValue == null) returnValue = transformedElem;
+ }
+ else
+ {
+ String newNamespace = (String)namespaces.get(nsUri);
+ if (newNamespace != null)
+ {
+ newQName = new QName(newNamespace, localName);
+ Element transformedElem = transformElem(currElem, newQName, prefixes);
+ if (returnValue == null) returnValue = transformedElem;
+ }
+ }
+ }
+ return returnValue;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private static Element transformElem(Element currElem, QName newQName, Map prefixes)
+ {
+ Element newElem = currElem.getOwnerDocument().createElementNS(newQName.nsUrl_,
+ (String) prefixes.get(newQName.nsUrl_) + ":" + newQName.localName_);
+
+ currElem.getParentNode().replaceChild(newElem, currElem);
+
+ // Treat attributes of currElem
+ NamedNodeMap currAttrs = currElem.getAttributes();
+ ArrayList currAttrsList = new ArrayList(currAttrs.getLength());
+ for (int i = 0; i < currAttrs.getLength(); i++) currAttrsList.add(currAttrs.item(i));
+ for (int i = 0; i < currAttrsList.size(); i++)
+ {
+ Attr currAttr = (Attr)currAttrsList.get(i);
+ currAttr.getOwnerElement().removeAttributeNode(currAttr);
+
+ // Workaround for bad Xerces behaviour: default attributes in the xml namespace are created without
+ // the xml prefix
+ if (Constants.NSURI_XML_.equals(currAttr.getNamespaceURI()) && "space".equals(currAttr.getLocalName()))
+ {
+ newElem.setAttributeNS(Constants.NSURI_XML_, "xml:space", currAttr.getValue());
+ }
+ else
+ {
+ newElem.setAttributeNode(currAttr);
+ }
+ }
+
+ // Treat child nodes of currElem
+ NodeList currChildren = currElem.getChildNodes();
+ ArrayList currChildrenList = new ArrayList(currChildren.getLength());
+ for (int i = 0; i < currChildren.getLength(); i++) currChildrenList.add(currChildren.item(i));
+ for (int i = 0; i < currChildrenList.size(); i++)
+ {
+ Node currChild = (Node)currChildrenList.get(i);
+ currElem.removeChild(currChild);
+ newElem.appendChild(currChild);
+ }
+
+ return newElem;
+ }
+}