aboutsummaryrefslogtreecommitdiff
path: root/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/SL2MOA.java
diff options
context:
space:
mode:
Diffstat (limited to 'spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/SL2MOA.java')
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/transformers/SL2MOA.java250
1 files changed, 247 insertions, 3 deletions
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
index 6c476e9ce..eec295bab 100644
--- 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
@@ -5,20 +5,49 @@
*/
package at.gv.egovernment.moa.spss.slinterface.transformers;
+import java.io.InputStream;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
import java.util.HashMap;
+import java.util.StringTokenizer;
+import javax.servlet.ServletException;
+
+import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.DOMUtils;
+import at.gv.egovernment.moa.spss.slinterface.XPathUtils;
/**
- * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ * @author Gregor Karlinger (mailto:gregor.karlinger@siemens.com)
*/
public class SL2MOA
{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_TRANSFORMERS_);
+
/**
- * Transforms an SL VerifyXMLSignatureRequest into a MOA VerifyXMLSignatureRequest.
+ * Transforms an SL <code>VerifyXMLSignatureRequest</code> into a MOA <code>VerifyXMLSignatureRequest
+ * </code> and makes the following additions to the resulting <code>VerifyXMLSignatureRequest</code>:
+ * <ul>
+ * <li>Insertion of a <code>DateTime</code> element to MOA <code>VerifyXMLSignatureRequest</code>, if no
+ * one exists and if no <code>etsi:SigningTime</code> element exists in the xml signature of the MOA
+ * VerifyXMLSinatureRequest</li> and if the creation time meta information could be extracted
+ * successfully from the E-Recht XML document signed by the XML signature contained in the
+ * MOA <code>VerifyXMLSignatureRequest</code> (see @link #extractXMLDocCreationTime(Element)).<li>
+ *
+ * <li>Addition of the <code>ReturnHashInputData</code> element indicating that MOA SP should return
+ * the hash input data for each <code>dsig:Reference</code> of the XML signature.</li>
+ *
+ * <li>Addition of the obligatory <code>TrustProfileID</code> element indicating the trust profile
+ * MOA ID should use for evaluating wheter the signer certificate used for creating the XML signature
+ * contained in the MOA <code>VerifyXMLSignatureRequest</code> is trusted.</li>
+ * </ul>
*
* @param slVerifyXMLSignatureRequest The SL VerifyXMLSignatureRequest to be transformed.
*
@@ -26,9 +55,11 @@ public class SL2MOA
* 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).
+ *
+ * @throws ServletException if transforming the request fails for any reason.
*/
public static Document toMoaVerifyXMLSignatureRequest(Document slVerifyXMLSignatureRequest,
- String trustProfileID)
+ String trustProfileID) throws ServletException
{
// Namespace to namespace prefix mapping
HashMap prefixMap = new HashMap(4);
@@ -77,6 +108,29 @@ public class SL2MOA
// Convert SL request into MOA request
verifyRequestElem = Utils.transformDeep(verifyRequestElem, prefixMap, nsTransforms, nameTransforms);
+ // Add DateTime element to MOA VerifyXMLSignature request, if
+ // - no one exists and
+ // - no etsi:SigningTime element exists in the xml signature of the MOA VerifyXMLSinatureRequest
+ if (!dateTimeExists(verifyRequestElem) && !signingTimeExists(verifyRequestElem))
+ {
+ // Extract creation date meta information from E-Recht XML document for use in MOA VerifyXMLSignature request
+ String dateTimeStr = extractXMLDocCreationTime(verifyRequestElem);
+
+ if (dateTimeStr != null)
+ {
+ // Creation date meta information could be extracted successfully from E-Recht XML document
+ Element dateTimeElem = slVerifyXMLSignatureRequest.createElementNS(
+ Constants.NSURI_MOA_12_, Constants.NSPRE_MOA_12_ + ":DateTime");
+ dateTimeElem.appendChild(slVerifyXMLSignatureRequest.createTextNode(dateTimeStr));
+ Element verifySignatureInfoElem = DOMUtils.getChildElem(verifyRequestElem, Constants.NSURI_MOA_12_, "VerifySignatureInfo");
+ verifyRequestElem.insertBefore(dateTimeElem, verifySignatureInfoElem);
+ }
+ else
+ {
+ logger_.warn("Could not extract creation date meta information from E-Recht XML document.");
+ }
+ }
+
// Add ReturnHashInputData element
Element returnHashInputDataElem = slVerifyXMLSignatureRequest.createElementNS(
Constants.NSURI_MOA_12_, Constants.NSPRE_MOA_12_ + ":ReturnHashInputData");
@@ -90,4 +144,194 @@ public class SL2MOA
return slVerifyXMLSignatureRequest;
}
+
+ /**
+ * Extracts the creation time meta information from the E-Recht XML document that is referenced by
+ * the XML signature contained in the specified MOA <code>VerifyXMLSignatureRequest</code>.
+ *
+ * @param verifyRequestElem The MOA <code>VerifyXMLSignatureRequest</code>. It is assumed that the
+ * request contains an XML signature which signs a E-Recht XML document
+ * (referring to the E-Recht XML document and transforming it to a corresponding
+ * XHTML representation respectively). The E-Recht XML document is assumed to
+ * have a root element with the name <code>erechtdok</code> in the namespace
+ * <code>http://www.bka.gv.at</code>. The creation time meta information is
+ * assumed to be contained in the attribute <code>h-created</code> of the root
+ * element. The value of the attribute <code>h-created</code> is assumed to have
+ * the format <code>dd. MMMMM yyyy, hh:mm:ss</code> where MMMMM denotes the month
+ * in German prose (see @link #convertMonth(String)).
+ *
+ * @return the extracted creation time meta information, or <code>null</code>, if the extraction fails for
+ * any reason.
+ */
+ private static String extractXMLDocCreationTime(Element verifyRequestElem)
+ {
+
+ // Get E-Recht XML document using location information in MOA VerifyXMLSignature request
+ String nSPrefixes = Constants.NSPRE_MOA_12_ + " " + Constants.NSURI_MOA_12_;
+ String xPathXMLDocumentLocContent =
+ "//" + Constants.NSPRE_MOA_12_ + ":SupplementProfile" +
+ "/" + Constants.NSPRE_MOA_12_ + ":Content[@Reference=\"dokument.xml\"]" +
+ "/" + Constants.NSPRE_MOA_12_ + ":LocRefContent";
+ Document xmlDocument = null;
+ try
+ {
+ XPathUtils utils = new XPathUtils();
+ utils.setupContext(xPathXMLDocumentLocContent, verifyRequestElem, nSPrefixes);
+ NodeList resultNL = utils.selectNodeSet(verifyRequestElem);
+
+ if (resultNL == null || resultNL.getLength() < 1)
+ {
+ logger_.warn("LocRefContent element for E-Recht XML document not found in MOA VerifyXMLSignatureRequest.");
+ return null;
+ }
+
+ URL locRefURL = new URL(DOMUtils.getText((Element) resultNL.item(0)));
+ InputStream locRefURLIS = locRefURL.openStream();
+ xmlDocument = DOMUtils.parseWellFormed(locRefURLIS);
+ }
+ catch (Exception e)
+ {
+ String message = "An error occurred while trying to load E-Recht XML document:";
+ logger_.warn(message, e);
+ return null;
+ }
+
+ // Extract attribute "h-created" from E-Recht XML document root element
+ String hCreated = xmlDocument.getDocumentElement().getAttributeNS(null, "h-created");
+ if (hCreated == null || "".equals(hCreated))
+ {
+ logger_.warn("Attribute \"h-created\" not found in E-Recht XML document root element.");
+ return null;
+ }
+
+ // Convert attribute "h-created" into a java date ("h-created" has formats like "10. März 2006, 11:15:09")
+ try
+ {
+ String dateStr = hCreated.substring(0, hCreated.indexOf(',')).trim();
+ String timeStr = hCreated.substring(hCreated.indexOf(',') + 1).trim();
+
+ StringTokenizer tokenizer = new StringTokenizer(dateStr, " ");
+ String dateDayStr = tokenizer.nextToken();
+ int dateDay = Integer.parseInt(dateDayStr.substring(0, dateDayStr.indexOf('.')));
+ String dateMonthAlphaStr = tokenizer.nextToken();
+ int dateMonthNum = convertMonth(dateMonthAlphaStr);
+ int dateYear = Integer.parseInt(tokenizer.nextToken());
+
+ tokenizer = new StringTokenizer(timeStr, ":");
+ int timeHours = Integer.parseInt(tokenizer.nextToken());
+ int timeMins = Integer.parseInt(tokenizer.nextToken());
+ int timeSecs = Integer.parseInt(tokenizer.nextToken());
+
+ GregorianCalendar calendar = new GregorianCalendar(dateYear, dateMonthNum, dateDay, timeHours, timeMins, timeSecs);
+ SimpleDateFormat dF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ return dF.format(calendar.getTime());
+ }
+ catch (Throwable t)
+ {
+ logger_.warn("Attribute \"h-created\" in E-Recht XML document root element has unexpected format: " + hCreated);
+ return null;
+ }
+ }
+
+ /**
+ * Converts the specified month name into a numeric representation as specified in @link Calendar, e.g.
+ * @link Calendar#JANUARY.
+ *
+ * @param dateMonthAlphaStr The specified month name; must be one of <code>Jänner</code>, <code>Januar</code>,
+ * <code>Februar</code>, <code>Feber</code>, <code>März</code>, <code>April</code>,
+ * <code>Mai</code>, <code>Juni</code>, <code>Juli</code>, <code>August</code>,
+ * <code>September</code>, <code>Oktober</code>, <code>November</code>, or
+ * <code>Dezember</code>.
+ *
+ * @return the numeric representation of the specified month.
+ *
+ * @throws Exception if <code>dateMonthAlphaStr</code> contains an invalid month name.
+ */
+ private static int convertMonth(String dateMonthAlphaStr) throws Exception
+ {
+ if ("Jänner".equalsIgnoreCase(dateMonthAlphaStr) || "Januar".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.JANUARY;
+ if ("Februar".equalsIgnoreCase(dateMonthAlphaStr) || "Feber".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.FEBRUARY;
+ if ("März".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.MARCH;
+ if ("April".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.APRIL;
+ if ("Mai".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.MAY;
+ if ("Juni".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.JUNE;
+ if ("Juli".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.JULY;
+ if ("August".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.AUGUST;
+ if ("September".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.SEPTEMBER;
+ if ("Oktober".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.OCTOBER;
+ if ("November".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.NOVEMBER;
+ if ("Dezember".equalsIgnoreCase(dateMonthAlphaStr)) return Calendar.DECEMBER;
+
+ String message = "Invalid month identifier found in attribute \"h-created\":" + dateMonthAlphaStr;
+ logger_.warn(message);
+ throw new Exception(message);
+ }
+
+ /**
+ * Checks wheter a <code>DateTime</code> element exists in the specified MOA <code>
+ * VerifyXMLSignatureRequest</code>.
+ *
+ * @param moaVerifyXMLSignatureRequest The MOA <code>VerifyXMLSingatureRequest</code>.
+ *
+ * @return <code>true</code> if the element exists, <code>false</code> otherwhise.
+ *
+ * @throws ServletException if the check fails for any reason.
+ */
+ private static boolean dateTimeExists(Element moaVerifyXMLSignatureRequest) throws ServletException
+ {
+ String nSPrefixes = Constants.NSPRE_MOA_12_ + " " + Constants.NSURI_MOA_12_;
+ String xPathDateTime = "//" + Constants.NSPRE_MOA_12_ + ":DateTime";
+
+ NodeList resultNL;
+ try
+ {
+ XPathUtils utils = new XPathUtils();
+ utils.setupContext(xPathDateTime, moaVerifyXMLSignatureRequest, nSPrefixes);
+ resultNL = utils.selectNodeSet(moaVerifyXMLSignatureRequest);
+ }
+ catch (Exception e)
+ {
+ String message = "An error occurred while checking for DateTime element in MOA VerifyXMLSignatureRequest:";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+
+ if (resultNL == null) return false;
+ if (resultNL.getLength() < 1) return false;
+ return true;
+ }
+
+ /**
+ * Checks whether an <code>etsi:SigningTime</code> signed attribute exists as part of the XML signature
+ * contained in the specified MOA <code>VerifyXMLSingatureRequest</code>.
+ *
+ * @param moaVerifyXMLSignatureRequest The MOA <code>VerifyXMLSingatureRequest</code>.
+ *
+ * @return <code>true</code>, if the attribute exists, <code>false</code> otherwhise.
+ *
+ * @throws ServletException if the check fails for any reason.
+ */
+ private static boolean signingTimeExists(Element moaVerifyXMLSignatureRequest) throws ServletException
+ {
+ String nSPrefixes = Constants.NSPRE_ETSI_ + " " + Constants.NSURI_ETSI_;
+ String xPathDateTime = "//" + Constants.NSPRE_ETSI_ + ":SigningTime";
+
+ NodeList resultNL;
+ try
+ {
+ XPathUtils utils = new XPathUtils();
+ utils.setupContext(xPathDateTime, moaVerifyXMLSignatureRequest, nSPrefixes);
+ resultNL = utils.selectNodeSet(moaVerifyXMLSignatureRequest);
+ }
+ catch (Exception e)
+ {
+ String message = "An error occurred while checking for " + Constants.NSPRE_ETSI_ + ":SigningTime element in XML signature in MOA VerifyXMLSignatureRequest:";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+
+ if (resultNL == null) return false;
+ if (resultNL.getLength() < 1) return false;
+ return true;
+ }
}