summaryrefslogtreecommitdiff
path: root/mocca-1.2.11/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
diff options
context:
space:
mode:
Diffstat (limited to 'mocca-1.2.11/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java')
-rw-r--r--mocca-1.2.11/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java1289
1 files changed, 0 insertions, 1289 deletions
diff --git a/mocca-1.2.11/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java b/mocca-1.2.11/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
deleted file mode 100644
index a57a11dd..00000000
--- a/mocca-1.2.11/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
+++ /dev/null
@@ -1,1289 +0,0 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.slcommands.impl.xsect;
-
-import iaik.xml.crypto.dom.DOMCryptoContext;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.SequenceInputStream;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.nio.charset.Charset;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.crypto.MarshalException;
-import javax.xml.crypto.dom.DOMStructure;
-import javax.xml.crypto.dsig.CanonicalizationMethod;
-import javax.xml.crypto.dsig.DigestMethod;
-import javax.xml.crypto.dsig.Reference;
-import javax.xml.crypto.dsig.Transform;
-import javax.xml.crypto.dsig.XMLObject;
-import javax.xml.crypto.dsig.spec.TransformParameterSpec;
-import javax.xml.crypto.dsig.spec.XPathFilter2ParameterSpec;
-import javax.xml.crypto.dsig.spec.XPathType;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.w3c.dom.DOMConfiguration;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentFragment;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-import org.w3c.dom.bootstrap.DOMImplementationRegistry;
-import org.w3c.dom.ls.DOMImplementationLS;
-import org.w3c.dom.ls.LSException;
-import org.w3c.dom.ls.LSInput;
-import org.w3c.dom.ls.LSOutput;
-import org.w3c.dom.ls.LSParser;
-import org.w3c.dom.ls.LSSerializer;
-
-import at.buergerkarte.namespaces.securitylayer._1.Base64XMLLocRefOptRefContentType;
-import at.buergerkarte.namespaces.securitylayer._1.DataObjectInfoType;
-import at.buergerkarte.namespaces.securitylayer._1.MetaInfoType;
-import at.buergerkarte.namespaces.securitylayer._1.TransformsInfoType;
-import at.gv.egiz.bku.binding.HttpUtil;
-import at.gv.egiz.bku.gui.viewer.MimeTypes;
-import at.gv.egiz.bku.slexceptions.SLCommandException;
-import at.gv.egiz.bku.slexceptions.SLRequestException;
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-import at.gv.egiz.bku.slexceptions.SLViewerException;
-import at.gv.egiz.bku.utils.urldereferencer.StreamData;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
-import at.gv.egiz.bku.viewer.ValidationException;
-import at.gv.egiz.bku.viewer.Validator;
-import at.gv.egiz.bku.viewer.ValidatorFactory;
-import at.gv.egiz.dom.DOMUtils;
-import at.gv.egiz.slbinding.impl.XMLContentType;
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-
-/**
- * This class represents a <code>DataObject</code> of an XML-Signature
- * created by the security layer command <code>CreateXMLSignature</code>.
- *
- * @author mcentner
- */
-public class DataObject {
-
- /**
- * Logging facility.
- */
- private static Log log = LogFactory.getLog(DataObject.class);
-
- /**
- * DOM Implementation.
- */
- private static final String DOM_LS_3_0 = "LS 3.0";
-
- /**
- * The array of the default preferred MIME type order.
- */
- private static final String[] DEFAULT_PREFFERED_MIME_TYPES =
- new String[] {
- "text/plain",
- "application/xhtml+xml"
- };
-
- /**
- * Validate hash input.
- */
- private static boolean validate = false;
-
- /**
- * Enable validation of hash data input.
- *
- * @param validate
- * <code>true</code> if validation should be enabled, or
- * <code>false</code> otherwise.
- */
- public static void enableHashDataInputValidation(boolean validate) {
- DataObject.validate = validate;
- }
-
- /**
- * @return <code>true</code> if hash data input validation is enabled,
- * or <code>false</code> otherwise.
- */
- public static boolean isHashDataInputValidationEnabled() {
- return validate;
- }
-
- /**
- * Valid MIME types.
- */
- private static String[] validMimeTypes = DEFAULT_PREFFERED_MIME_TYPES;
-
- /**
- * Sets the list of valid hash data input media types.
- * <p>The array is also used for transformation path selection.
- * The transformation path with a final type, that appears in the
- * given array in the earliest position is used selected.</p>
- *
- * @param mediaTypes an array of MIME media types.
- */
- public static void setValidHashDataInputMediaTypes(String[] mediaTypes) {
- validMimeTypes = mediaTypes;
- }
-
- /**
- * The DOM implementation used.
- */
- private DOMImplementationLS domImplLS;
-
- /**
- * The signature context.
- */
- private SignatureContext ctx;
-
- /**
- * The Reference for this DataObject.
- */
- private XSECTReference reference;
-
- /**
- * The XMLObject for this DataObject.
- */
- private XMLObject xmlObject;
-
- /**
- * The MIME-Type of the digest input.
- */
- private String mimeType;
-
- /**
- * An optional description of the digest input.
- */
- private String description;
-
- private String filename;
-
- /**
- * Creates a new instance.
- *
- * @param document the document of the target signature
- */
- public DataObject(SignatureContext signatureContext) {
- this.ctx = signatureContext;
-
- DOMImplementationRegistry registry;
- try {
- registry = DOMImplementationRegistry.newInstance();
- } catch (Exception e) {
- log.error("Failed to get DOMImplementationRegistry.", e);
- throw new SLRuntimeException("Failed to get DOMImplementationRegistry.");
- }
-
- domImplLS = (DOMImplementationLS) registry.getDOMImplementation(DOM_LS_3_0);
- if (domImplLS == null) {
- log.error("Failed to get DOMImplementation " + DOM_LS_3_0);
- throw new SLRuntimeException("Failed to get DOMImplementation " + DOM_LS_3_0);
- }
-
- }
-
- /**
- * @return the reference
- */
- public Reference getReference() {
- return reference;
- }
-
- /**
- * @return the xmlObject
- */
- public XMLObject getXmlObject() {
- return xmlObject;
- }
-
- /**
- * @return the mimeType
- */
- public String getMimeType() {
- return mimeType;
- }
-
- public String getFilename() {
- return filename;
- }
-
- /**
- * @return the description
- */
- public String getDescription() {
- return description;
- }
-
- public void validateHashDataInput() throws SLViewerException {
-
- if (validate) {
-
- if (reference == null) {
- log.error("Medthod validateHashDataInput() called before reference has been created.");
- throw new SLViewerException(5000);
- }
-
- InputStream digestInputStream = reference.getDigestInputStream();
- if (digestInputStream == null) {
- log.error("Method validateHashDataInput() called before reference has been generated " +
- "or reference caching is not enabled.");
- throw new SLViewerException(5000);
- }
-
- if (mimeType == null) {
- log.info("FinalDataMetaInfo does not specify MIME type of to be signed data.");
- // TODO: add detailed message
- throw new SLViewerException(5000);
- }
-
- // get MIME media type
- String mediaType = mimeType.split(";")[0].trim();
- // and optional charset
- String charset = HttpUtil.getCharset(mimeType, false);
-
- if (Arrays.asList(validMimeTypes).contains(mediaType)) {
-
- Validator validator;
- try {
- validator = ValidatorFactory.newValidator(mediaType);
- } catch (IllegalArgumentException e) {
- log.error("No validator found for mime type '" + mediaType + "'.");
- throw new SLViewerException(5000);
- }
-
- try {
- validator.validate(digestInputStream, charset);
- } catch (ValidationException e) {
- if ("text/plain".equals(mediaType)) {
- log.info("Data to be displayed contains unsupported characters.", e);
- // TODO: add detailed message
- throw new SLViewerException(5003);
- } else if ("application/xhtml+xml".equals(mediaType)) {
- // TODO: add detailed message
- log.info("Standard display format: HTML does not conform to specification.", e);
- throw new SLViewerException(5004);
- } else {
- // TODO: add detailed message
- log.info("Data to be displayed is invalid.", e);
- throw new SLViewerException(5000);
- }
- }
-
- } else {
- log.debug("MIME media type '" + mediaType + "' is not a s/valid/SUPPORTED digest input, omitting validation.");
- }
- }
-
- }
-
- /**
- * Configures this DataObject with the information provided within the given
- * <code>sl:DataObjectInfo</code>.
- *
- * @param dataObjectInfo
- * the <code>sl:DataObjectInfo</code>
- *
- * @throws SLCommandException
- * if configuring this DataObject with the information provided in
- * the <code>sl:DataObjectInfo</code> fails.
- * @throws SLRequestException
- * if the information provided in the <code>sl:DataObjectInfo</code>
- * does not conform to the security layer specification.
- * @throws NullPointerException
- * if <code>dataObjectInfo</code> is <code>null</code>
- */
- public void setDataObjectInfo(DataObjectInfoType dataObjectInfo) throws SLCommandException, SLRequestException {
-
- Base64XMLLocRefOptRefContentType dataObject = dataObjectInfo.getDataObject();
- String structure = dataObjectInfo.getStructure();
-
- // select and unmarshal an appropriate transformation path if provided
- // and set the final data meta information
- XSECTTransforms transforms = createTransformsAndSetFinalDataMetaInfo(dataObjectInfo.getTransformsInfo());
-
- if ("enveloping".equals(structure)) {
-
- // configure this DataObject as an enveloped DataObject
- setEnvelopedDataObject(dataObject, transforms);
-
- } else if ("detached".equals(structure)) {
-
- // configure this DataObject as an detached DataObject
- setDetachedDataObject(dataObject, transforms);
-
- }
- // other values are not allowed by the schema and are therefore ignored
-
- this.filename = deriveFilename();
- }
-
- /**
- * Extract filename from reference URI
- * or propose reference Id with an apropriate (mime-type) file extension
- *
- * @return if neither reference nor id can be extracted return null (or data.extension?)
- */
- private String deriveFilename() {
-
- String filename = null;
-
- if (reference != null) {
- if (reference.getURI() != null && !"".equals(reference.getURI())) {
- try {
- log.info("deriving filename from reference URI " + reference.getURI());
- URI refURI = new URI(reference.getURI());
-
- if (refURI.isOpaque()) {
- // could check scheme component, but also allow other schemes (e.g. testlocal)
- log.trace("opaque reference URI, use scheme-specific part as filename");
- filename = refURI.getSchemeSpecificPart();
- if (!hasExtension(filename)) {
- filename += MimeTypes.getExtension(mimeType);
- }
- // else hierarchical URI:
- // for shorthand xpointer use fragment as filename,
- // for any other xpointer use reference Id and
- // for any other hierarchical (absolute or relative) use filename (ignore fragment, see xmldsig section 4.3.3.2: fragments not recommendet)
- } else if ("".equals(refURI.getPath()) &&
- refURI.getFragment() != null &&
- refURI.getFragment().indexOf('(') < 0) { // exclude (schemebased) xpointer expressions
- log.trace("fragment (shorthand xpointer) URI, use fragment as filename");
- filename = refURI.getFragment();
- if(!hasExtension(filename)) {
- filename += MimeTypes.getExtension(mimeType);
- }
- } else if (!"".equals(refURI.getPath())) {
- log.trace("hierarchical URI with path component, use path as filename");
- File refFile = new File(refURI.getPath());
- filename = refFile.getName();
- if(!hasExtension(filename)) {
- filename += MimeTypes.getExtension(mimeType);
- }
- } else {
- log.debug("failed to derive filename from URI '" + refURI + "', derive filename from reference ID");
- filename = reference.getId() + MimeTypes.getExtension(mimeType);
- }
- } catch (URISyntaxException ex) {
- log.error("failed to derive filename from invalid URI " + ex.getMessage());
- filename = reference.getId() + MimeTypes.getExtension(mimeType);
- }
- } else {
- log.debug("same-document URI, derive filename from reference ID");
- filename = reference.getId() + MimeTypes.getExtension(mimeType);
- }
- } else {
- log.error("failed to derive filename, no reference created");
- }
- log.debug("derived filename for reference " + reference.getId() + ": " + filename);
- return filename;
- }
-
- private static boolean hasExtension(String filename) {
- int extDelimiterInd = filename.lastIndexOf('.');
- return extDelimiterInd >= 0 && extDelimiterInd >= filename.length() - 4;
- }
-
- private byte[] getTransformsBytes(at.gv.egiz.slbinding.impl.TransformsInfoType ti) {
- return ti.getRedirectedStream().toByteArray();
-// byte[] transformsBytes = ti.getRedirectedStream().toByteArray();
-//
-// if (transformsBytes == null || transformsBytes.length == 0) {
-// return null;
-// }
-//
-// String dsigPrefix = ti.getNamespaceContext().getNamespaceURI("http://www.w3.org/2000/09/xmldsig#");
-// byte[] pre, post;
-// if (dsigPrefix == null) {
-// log.trace("XMLDSig not declared in outside dsig:Transforms");
-// pre = "<AssureDSigNS>".getBytes();
-// post = "</AssureDSigNS>".getBytes();
-// } else {
-// log.trace("XMLDSig bound to prefix " + dsigPrefix);
-// pre = ("<AssureDSigNS xmlns:" + dsigPrefix + "=\"http://www.w3.org/2000/09/xmldsig#\">").getBytes();
-// post = "</AssureDSigNS>".getBytes();
-// }
-//
-// byte[] workaround = new byte[pre.length + transformsBytes.length + post.length];
-// System.arraycopy(pre, 0, workaround, 0, pre.length);
-// System.arraycopy(transformsBytes, 0, workaround, pre.length, transformsBytes.length);
-// System.arraycopy(post, 0, workaround, pre.length + transformsBytes.length, post.length);
-// return workaround;
- }
-
- /**
- * Configures this DataObject as an enveloped DataObject with the information
- * provided within the given <code>sl:DataObject</code>.
- *
- * @param dataObject
- * the <code>sl:DataObject</code>
- * @param transforms
- * an optional <code>Transforms</code> element (may be
- * <code>null</code>)
- *
- * @throws SLCommandException
- * if configuring this DataObject with the information provided in
- * the <code>sl:DataObject</code> fails.
- * @throws SLRequestException
- * if the information provided in the <code>sl:DataObject</code>
- * does not conform to the security layer specification.
- * @throws NullPointerException
- * if <code>dataObject</code> is <code>null</code>
- */
- private void setEnvelopedDataObject(
- Base64XMLLocRefOptRefContentType dataObject, XSECTTransforms transforms)
- throws SLCommandException, SLRequestException {
-
- String reference = dataObject.getReference();
- if (reference == null) {
- //
- // case A
- //
- // The Reference attribute is not used; the content of sl:DataObject represents the data object.
- // If the data object is XML-coded (the sl:XMLContent element is used in sl:DataObject), then it
- // must be incorporated in the signature structure as parsed XML.
- //
-
- if (dataObject.getBase64Content() != null) {
-
- log.debug("Adding DataObject (Base64Content) without a reference URI.");
-
- // create XMLObject
- XMLObject xmlObject = createXMLObject(new ByteArrayInputStream(dataObject.getBase64Content()));
-
- setXMLObjectAndReferenceBase64(xmlObject, transforms);
-
- } else if (dataObject.getXMLContent() != null) {
-
- log.debug("Adding DataObject (XMLContent) without a reference URI.");
-
- // create XMLObject
- DocumentFragment content = parseDataObject((XMLContentType) dataObject.getXMLContent());
- XMLObject xmlObject = createXMLObject(content);
-
- setXMLObjectAndReferenceXML(xmlObject, transforms);
-
- } else if (dataObject.getLocRefContent() != null) {
-
- log.debug("Adding DataObject (LocRefContent) without a reference URI.");
-
- setEnvelopedDataObject(dataObject.getLocRefContent(), transforms);
-
- } else {
-
- // not allowed
- log.info("XML structure of the command request contains an " +
- "invalid combination of optional elements or attributes. " +
- "DataObject of structure='enveloped' without a reference must contain content.");
- throw new SLRequestException(3003);
-
- }
-
- } else {
-
- if (dataObject.getBase64Content() == null &&
- dataObject.getXMLContent() == null &&
- dataObject.getLocRefContent() == null) {
-
- //
- // case B
- //
- // The Reference attribute contains a URI that must be resolved by the
- // Citizen Card Environment to obtain the data object.
- // The content of sl:DataObject remains empty
- //
-
- log.debug("Adding DataObject from reference URI '" + reference + "'.");
-
- setEnvelopedDataObject(reference, transforms);
-
- } else {
-
- // not allowed
- log.info("XML structure of the command request contains an " +
- "invalid combination of optional elements or attributes. " +
- "DataObject of structure='enveloped' with reference must not contain content.");
- throw new SLRequestException(3003);
-
- }
-
-
- }
-
- }
-
- /**
- * Configures this DataObject as an enveloped DataObject with the content to
- * be dereferenced from the given <code>reference</code>.
- *
- * @param reference
- * the <code>reference</code> URI
- * @param transforms
- * an optional <code>Transforms</code> element (may be
- * <code>null</code>)
- *
- * @throws SLCommandException
- * if dereferencing the given <code>reference</code> fails, or if
- * configuring this DataObject with the data dereferenced from the
- * given <code>reference</code> fails.
- * @throws NullPointerException
- * if <code>reference</code> is <code>null</code>
- */
- private void setEnvelopedDataObject(String reference, XSECTTransforms transforms) throws SLCommandException {
-
- if (reference == null) {
- throw new NullPointerException("Argument 'reference' must not be null.");
- }
-
- // dereference URL
- URLDereferencer dereferencer = URLDereferencer.getInstance();
-
- StreamData streamData;
- try {
- streamData = dereferencer.dereference(reference, ctx.getDereferencerContext());
- } catch (IOException e) {
- log.info("Failed to dereference XMLObject from '" + reference + "'.", e);
- throw new SLCommandException(4110);
- }
-
- Node childNode;
-
- String contentType = streamData.getContentType();
- if (contentType.startsWith("text/xml")) {
-
- // If content type is text/xml parse content.
- String charset = HttpUtil.getCharset(contentType, true);
-
- Document doc = parseDataObject(streamData.getStream(), charset);
-
- childNode = doc.getDocumentElement();
-
- if (childNode == null) {
- log.info("Failed to parse XMLObject from '" + reference + "'.");
- throw new SLCommandException(4111);
- }
-
- XMLObject xmlObject = createXMLObject(childNode);
-
- setXMLObjectAndReferenceXML(xmlObject, transforms);
-
- } else {
-
- // Include content Base64 encoded.
- XMLObject xmlObject = createXMLObject(streamData.getStream());
-
- setXMLObjectAndReferenceBase64(xmlObject, transforms);
-
- }
-
- }
-
- /**
- * Configures this DataObject as an detached DataObject with the information
- * provided in the given <code>sl:DataObject</code> and optionally
- * <code>transforms</code>.
- *
- * @param dataObject
- * the <code>sl:DataObject</code>
- * @param transforms
- * an optional Transforms object, may be <code>null</code>
- *
- * @throws SLCommandException
- * if configuring this DataObject with the information provided in
- * the <code>sl:DataObject</code> fails.
- * @throws SLRequestException
- * if the information provided in the <code>sl:DataObject</code>
- * does not conform to the security layer specification.
- * @throws NullPointerException
- * if <code>dataObject</code> is <code>null</code>
- */
- private void setDetachedDataObject(
- Base64XMLLocRefOptRefContentType dataObject, XSECTTransforms transforms)
- throws SLCommandException, SLRequestException {
-
- String referenceURI = dataObject.getReference();
-
- if (referenceURI == null) {
-
- // not allowed
- log.info("XML structure of the command request contains an " +
- "invalid combination of optional elements or attributes. " +
- "DataObject of structure='detached' must contain a reference.");
- throw new SLRequestException(3003);
-
- } else {
-
- DigestMethod dm;
- try {
- dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
- } catch (NoSuchAlgorithmException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- } catch (InvalidAlgorithmParameterException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- }
-
- String idValue = ctx.getIdValueFactory().createIdValue("Reference");
-
- reference = new XSECTReference(referenceURI, dm, transforms, null, idValue);
-
- // case D:
- //
- // The Reference attribute contains a URI that is used by the Citizen Card
- // Environment to code the reference to the data object as part of the XML
- // signature (attribute URI in the dsig:Reference) element. The content of
- // sl:DataObject represents the data object.
-
- if (dataObject.getLocRefContent() != null) {
- String locRef = dataObject.getLocRefContent();
- try {
- this.reference.setDereferencer(new LocRefDereferencer(ctx.getDereferencerContext(), locRef));
- } catch (URISyntaxException e) {
- log.info("Invalid URI '" + locRef + "' in DataObject.", e);
- throw new SLCommandException(4003);
- } catch (IllegalArgumentException e) {
- log.info("LocRef URI of '" + locRef + "' not supported in DataObject. ", e);
- throw new SLCommandException(4003);
- }
- } else if (dataObject.getBase64Content() != null) {
- byte[] base64Content = dataObject.getBase64Content();
- this.reference.setDereferencer(new ByteArrayDereferencer(base64Content));
- } else if (dataObject.getXMLContent() != null) {
- XMLContentType xmlContent = (XMLContentType) dataObject.getXMLContent();
- byte[] bytes = xmlContent.getRedirectedStream().toByteArray();
- this.reference.setDereferencer(new ByteArrayDereferencer(bytes));
- } else {
-
- // case C:
- //
- // The Reference attribute contains a URI that must be resolved by the
- // Citizen Card Environment to obtain the data object. The Reference
- // attribute contains a URI that is used by the Citizen Card Environment
- // to code the reference to the data object as part of the XML signature
- // (attribute URI in the dsig:Reference) element. The content of
- // sl:DataObject remains empty.
-
- }
-
- }
- }
-
- /**
- * Returns the preferred <code>sl:TransformInfo</code> from the given list of
- * <code>transformInfos</code>, or <code>null</code> if none of the given
- * <code>transformInfos</code> is preferred over the others.
- *
- * @param transformsInfos
- * a list of <code>sl:TransformInfo</code>s
- *
- * @return the selected <code>sl:TransformInfo</code> or <code>null</code>, if
- * none is preferred over the others
- */
- private TransformsInfoType selectPreferredTransformsInfo(List<TransformsInfoType> transformsInfos) {
-
- Map<String, TransformsInfoType> mimeTypes = new HashMap<String, TransformsInfoType>();
-
- StringBuilder debugString = null;
- if (log.isDebugEnabled()) {
- debugString = new StringBuilder();
- debugString.append("Got " + transformsInfos.size() + " TransformsInfo(s):");
- }
-
- for (TransformsInfoType transformsInfoType : transformsInfos) {
- MetaInfoType finalDataMetaInfo = transformsInfoType.getFinalDataMetaInfo();
- String mimeType = finalDataMetaInfo.getMimeType();
- String description = finalDataMetaInfo.getDescription();
- mimeTypes.put(mimeType, transformsInfoType);
- if (debugString != null) {
- debugString.append("\n FinalDataMetaInfo: MIME-Type=");
- debugString.append(mimeType);
- if (description != null) {
- debugString.append(" ");
- debugString.append(description);
- }
- }
- }
-
- if (debugString != null) {
- log.debug(debugString);
- }
-
- // look for preferred transform
- for (String mimeType : DEFAULT_PREFFERED_MIME_TYPES) {
- if (mimeTypes.containsKey(mimeType)) {
- return mimeTypes.get(mimeType);
- }
- }
-
- // no preferred transform
- return null;
-
- }
-
- /**
- * Create an instance of <code>ds:Transforms</code> from the given
- * <code>sl:TransformsInfo</code>.
- *
- * @param transformsInfo
- * the <code>sl:TransformsInfo</code>
- *
- * @return a corresponding unmarshalled <code>ds:Transforms</code>, or
- * <code>null</code> if the given <code>sl:TransformsInfo</code> does
- * not contain a <code>dsig:Transforms</code> element
- *
- * @throws SLRequestException
- * if the <code>ds:Transforms</code> in the given
- * <code>transformsInfo</code> are not valid or cannot be parsed.
- *
- * @throws MarshalException
- * if the <code>ds:Transforms</code> in the given
- * <code>transformsInfo</code> cannot be unmarshalled.
- */
- private XSECTTransforms createTransforms(TransformsInfoType transformsInfo) throws SLRequestException, MarshalException {
-
- byte[] transforms = getTransformsBytes((at.gv.egiz.slbinding.impl.TransformsInfoType) transformsInfo);
-
- if (transforms != null && transforms.length > 0) {
- // debug
- if (log.isTraceEnabled()) {
- StringBuilder sb = new StringBuilder();
- sb.append("Trying to parse transforms:\n");
- sb.append(new String(transforms, Charset.forName("UTF-8")));
- log.trace(sb);
- }
-
- DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
- LSInput input = domImplLS.createLSInput();
- input.setByteStream(new ByteArrayInputStream(transforms));
-
- LSParser parser = domImplLS.createLSParser(
- DOMImplementationLS.MODE_SYNCHRONOUS, null);
- DOMConfiguration domConfig = parser.getDomConfig();
- SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
- domConfig.setParameter("error-handler", errorHandler);
- domConfig.setParameter("validate", Boolean.FALSE);
-
- Document document;
- try {
- document = parser.parse(input);
- } catch (DOMException e) {
- log.info("Failed to parse dsig:Transforms.", e);
- throw new SLRequestException(3002);
- } catch (LSException e) {
- log.info("Failed to parse dsig:Transforms.", e);
- throw new SLRequestException(3002);
- }
-
- // adopt ds:Transforms
- Element transformsElt = document.getDocumentElement();
- Node adoptedTransforms = ctx.getDocument().adoptNode(transformsElt);
-
- DOMCryptoContext context = new DOMCryptoContext();
-
- // unmarshall ds:Transforms
- return new XSECTTransforms(context, adoptedTransforms);
-
- } else {
- return null;
- }
-
-
-// TransformsType transformsType = transformsInfo.getTransforms();
-// if (transformsType == null) {
-// return null;
-// }
-// List<TransformType> transformList = transformsType.getTransform();
-//
-// DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
-//// Document transformsDoc = ((DOMImplementation) domImplLS).createDocument("http://www.w3.org/2000/09/xmldsig#", "Transforms", null);
-//// Element transforms = transformsDoc.getDocumentElement();
-// Document transformsDoc = DOMUtils.createDocument();
-// Element transforms = transformsDoc.createElementNS(
-// "http://www.w3.org/2000/09/xmldsig#",
-// Signature.XMLDSIG_PREFIX + ":Transforms");
-// transformsDoc.appendChild(transforms);
-//
-// for (TransformType transformType : transformList) {
-// log.trace("found " + transformType.getClass().getName());
-// Element transform = transformsDoc.createElementNS(
-// "http://www.w3.org/2000/09/xmldsig#",
-// Signature.XMLDSIG_PREFIX + ":Transform");
-// String algorithm = transformType.getAlgorithm();
-// if (algorithm != null) {
-// log.trace("found algorithm " + algorithm);
-// transform.setAttribute("Algorithm", algorithm);
-// }
-//
-// at.gv.egiz.slbinding.impl.TransformType t = (at.gv.egiz.slbinding.impl.TransformType) transformType;
-// byte[] redirectedBytes = t.getRedirectedStream().toByteArray();
-// if (redirectedBytes != null && redirectedBytes.length > 0) {
-// if (log.isTraceEnabled()) {
-// StringBuilder sb = new StringBuilder();
-// sb.append("Trying to parse dsig:Transform:\n");
-// sb.append(new String(redirectedBytes, Charset.forName("UTF-8")));
-// log.trace(sb);
-// }
-// LSInput input = domImplLS.createLSInput();
-// input.setByteStream(new ByteArrayInputStream(redirectedBytes));
-//
-// LSParser parser = domImplLS.createLSParser(
-// DOMImplementationLS.MODE_SYNCHRONOUS, null);
-// DOMConfiguration domConfig = parser.getDomConfig();
-// SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
-// domConfig.setParameter("error-handler", errorHandler);
-// domConfig.setParameter("validate", Boolean.FALSE);
-//
-// try {
-// Document redirectedDoc = parser.parse(input);
-// Node redirected = transformsDoc.adoptNode(redirectedDoc.getDocumentElement());
-// transform.appendChild(redirected);
-//
-// //not supported by Xerces2.9.1
-//// Node redirected = parser.parseWithContext(input, transform, LSParser.ACTION_APPEND_AS_CHILDREN);
-//
-// } catch (DOMException e) {
-// log.info("Failed to parse dsig:Transform.", e);
-// throw new SLRequestException(3002);
-// } catch (LSException e) {
-// log.info("Failed to parse dsig:Transform.", e);
-// throw new SLRequestException(3002);
-// }
-// }
-// transforms.appendChild(transform);
-// }
-//
-// //adopt ds:Transforms
-// Node adoptedTransforms = ctx.getDocument().adoptNode(transforms);
-// DOMCryptoContext context = new DOMCryptoContext();
-//
-// // unmarshall ds:Transforms
-// return new XSECTTransforms(context, adoptedTransforms);
-
- }
-
- /**
- * Sets the <code>mimeType</code> and the <code>description</code> value
- * for this DataObject.
- *
- * @param metaInfoType the <code>sl:FinalMetaDataInfo</code>
- *
- * @throws NullPointerException if <code>metaInfoType</code> is <code>null</code>
- */
- private void setFinalDataMetaInfo(MetaInfoType metaInfoType) {
-
- this.mimeType = metaInfoType.getMimeType();
- this.description = metaInfoType.getDescription();
-
- }
-
- /**
- * Selects an appropriate transformation path (if present) from the given list
- * of <code>sl:TransformInfos</code>, sets the corresponding final data meta info and
- * returns the corresponding unmarshalled <code>ds:Transforms</code>.
- *
- * @param transformsInfos the <code>sl:TransformInfos</code>
- *
- * @return the unmarshalled <code>ds:Transforms</code>, or <code>null</code> if
- * no transformation path has been selected.
- *
- * @throws SLRequestException if the given list <code>ds:TransformsInfo</code> contains
- * an invalid <code>ds:Transforms</code> element, or no suitable transformation path
- * can be found.
- */
- private XSECTTransforms createTransformsAndSetFinalDataMetaInfo(
- List<TransformsInfoType> transformsInfos) throws SLRequestException {
-
- TransformsInfoType preferredTransformsInfo = selectPreferredTransformsInfo(transformsInfos);
- // try preferred transform
- if (preferredTransformsInfo != null) {
-
- try {
- XSECTTransforms transforms = createTransforms(preferredTransformsInfo);
- setFinalDataMetaInfo(preferredTransformsInfo.getFinalDataMetaInfo());
- return transforms;
- } catch (MarshalException e) {
-
- String mimeType = preferredTransformsInfo.getFinalDataMetaInfo().getMimeType();
- log.info("Failed to unmarshal preferred transformation path (MIME-Type="
- + mimeType + ").", e);
-
- }
-
- }
-
- // look for another suitable transformation path
- for (TransformsInfoType transformsInfoType : transformsInfos) {
-
- try {
- XSECTTransforms transforms = createTransforms(transformsInfoType);
- setFinalDataMetaInfo(transformsInfoType.getFinalDataMetaInfo());
- return transforms;
- } catch (MarshalException e) {
-
- String mimeType = transformsInfoType.getFinalDataMetaInfo().getMimeType();
- log.info("Failed to unmarshal transformation path (MIME-Type="
- + mimeType + ").", e);
- }
-
- }
-
- // no suitable transformation path found
- throw new SLRequestException(3003);
-
- }
-
- /**
- * Create an XMLObject with the Base64 encoding of the given
- * <code>content</code>.
- *
- * @param content
- * the to-be Base64 encoded content
- * @return an XMLObject with the Base64 encoded <code>content</code>
- */
- private XMLObject createXMLObject(InputStream content) {
-
- Text textNode;
- try {
- textNode = at.gv.egiz.dom.DOMUtils.createBase64Text(content, ctx.getDocument());
- } catch (IOException e) {
- log.error(e);
- throw new SLRuntimeException(e);
- }
-
- DOMStructure structure = new DOMStructure(textNode);
-
- String idValue = ctx.getIdValueFactory().createIdValue("Object");
-
- return ctx.getSignatureFactory().newXMLObject(Collections.singletonList(structure), idValue, null, null);
-
- }
-
- /**
- * Create an XMLObject with the given <code>content</code> node.
- *
- * @param content the content node
- *
- * @return an XMLObject with the given <code>content</code>
- */
- private XMLObject createXMLObject(Node content) {
-
- String idValue = ctx.getIdValueFactory().createIdValue("Object");
-
- List<DOMStructure> structures = Collections.singletonList(new DOMStructure(content));
-
- return ctx.getSignatureFactory().newXMLObject(structures, idValue, null, null);
-
- }
-
- /**
- * Sets the given <code>xmlObject</code> and creates and sets a corresponding
- * <code>Reference</code>.
- * <p>
- * A transform to Base64-decode the xmlObject's content is inserted at the top
- * of to the optional <code>transforms</code> if given, or to a newly created
- * <code>Transforms</code> element if <code>transforms</code> is
- * <code>null</code>.
- *
- * @param xmlObject
- * the XMLObject
- * @param transforms
- * an optional <code>Transforms</code> element (may be
- * <code>null</code>)
- *
- * @throws SLCommandException
- * if creating the Reference fails
- * @throws NullPointerException
- * if <code>xmlObject</code> is <code>null</code>
- */
- private void setXMLObjectAndReferenceBase64(XMLObject xmlObject, XSECTTransforms transforms) throws SLCommandException {
-
- // create reference URI
- //
- // NOTE: the ds:Object can be referenced directly, as the Base64 transform
- // operates on the text() of the input nodelist.
- //
- String referenceURI = "#" + xmlObject.getId();
-
- // create Base64 Transform
- Transform transform;
- try {
- transform = ctx.getSignatureFactory().newTransform(Transform.BASE64, (TransformParameterSpec) null);
- } catch (NoSuchAlgorithmException e) {
- // algorithm must be present
- throw new SLRuntimeException(e);
- } catch (InvalidAlgorithmParameterException e) {
- // algorithm does not take parameters
- throw new SLRuntimeException(e);
- }
-
- if (transforms == null) {
- transforms = new XSECTTransforms(Collections.singletonList(transform));
- } else {
- transforms.insertTransform(transform);
- }
-
- DigestMethod dm;
- try {
- dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
- } catch (NoSuchAlgorithmException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- } catch (InvalidAlgorithmParameterException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- }
- String id = ctx.getIdValueFactory().createIdValue("Reference");
-
- this.xmlObject = xmlObject;
- this.reference = new XSECTReference(referenceURI, dm, transforms, null, id);
-
- }
-
- /**
- * Sets the given <code>xmlObject</code> and creates and sets a corresponding
- * <code>Reference</code>.
- * <p>
- * A transform to select the xmlObject's content is inserted at the top of to
- * the optional <code>transforms</code> if given, or to a newly created
- * <code>Transforms</code> element if <code>transforms</code> is
- * <code>null</code>.
- * </p>
- *
- * @param xmlObject
- * the XMLObject
- * @param transforms
- * an optional <code>Transforms</code> element (may be
- * <code>null</code>)
- *
- * @throws SLCommandException
- * if creating the Reference fails
- * @throws NullPointerException
- * if <code>xmlObject</code> is <code>null</code>
- */
- private void setXMLObjectAndReferenceXML(XMLObject xmlObject, XSECTTransforms transforms) throws SLCommandException {
-
- // create reference URI
- String referenceURI = "#" + xmlObject.getId();
-
- // create Transform to select ds:Object's children
- Transform xpathTransform;
- Transform c14nTransform;
- try {
-
- XPathType xpath = new XPathType("id(\"" + xmlObject.getId() + "\")/node()", XPathType.Filter.INTERSECT);
- List<XPathType> xpaths = Collections.singletonList(xpath);
- XPathFilter2ParameterSpec params = new XPathFilter2ParameterSpec(xpaths);
-
- xpathTransform = ctx.getSignatureFactory().newTransform(Transform.XPATH2, params);
-
- // add exclusive canonicalization to avoid signing the namespace context of the ds:Object
- c14nTransform = ctx.getSignatureFactory().newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null);
-
- } catch (NoSuchAlgorithmException e) {
- // algorithm must be present
- throw new SLRuntimeException(e);
- } catch (InvalidAlgorithmParameterException e) {
- // params must be appropriate
- throw new SLRuntimeException(e);
- }
-
- if (transforms == null) {
- List<Transform> newTransfroms = new ArrayList<Transform>();
- newTransfroms.add(xpathTransform);
- newTransfroms.add(c14nTransform);
- transforms = new XSECTTransforms(newTransfroms);
- } else {
- transforms.insertTransform(xpathTransform);
- }
-
- DigestMethod dm;
- try {
- dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
- } catch (NoSuchAlgorithmException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- } catch (InvalidAlgorithmParameterException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- }
- String id = ctx.getIdValueFactory().createIdValue("Reference");
-
- this.xmlObject = xmlObject;
- this.reference = new XSECTReference(referenceURI, dm, transforms, null, id);
-
- }
-
- /**
- * Parses the given <code>xmlContent</code> and returns a corresponding
- * document fragment.
- *
- * <p>
- * The to-be parsed content is surrounded by <dummy> ... </dummy> elements to
- * allow for mixed (e.g. Text and Element) content in XMLContent.
- * </p>
- *
- * @param xmlContent
- * the XMLContent to-be parsed
- *
- * @return a document fragment containing the parsed nodes
- *
- * @throws SLCommandException
- * if parsing the given <code>xmlContent</code> fails
- *
- * @throws NullPointerException
- * if <code>xmlContent</code> is <code>null</code>
- */
- private DocumentFragment parseDataObject(XMLContentType xmlContent) throws SLCommandException {
-
- ByteArrayOutputStream redirectedStream = xmlContent.getRedirectedStream();
-
- // Note: We can assume a fixed character encoding of UTF-8 for the
- // content of the redirect stream as the content has already been parsed
- // and serialized again to the redirect stream.
-
- List<InputStream> inputStreams = new ArrayList<InputStream>();
- try {
- // dummy start element
- inputStreams.add(new ByteArrayInputStream("<dummy>".getBytes("UTF-8")));
-
- // content
- inputStreams.add(new ByteArrayInputStream(redirectedStream.toByteArray()));
-
- // dummy end element
- inputStreams.add(new ByteArrayInputStream("</dummy>".getBytes("UTF-8")));
- } catch (UnsupportedEncodingException e) {
- throw new SLRuntimeException(e);
- }
-
- SequenceInputStream inputStream = new SequenceInputStream(Collections.enumeration(inputStreams));
-
- // parse DataObject
- Document doc = parseDataObject(inputStream, "UTF-8");
-
- Element documentElement = doc.getDocumentElement();
-
- if (documentElement == null ||
- !"dummy".equals(documentElement.getLocalName())) {
- log.info("Failed to parse DataObject XMLContent.");
- throw new SLCommandException(4111);
- }
-
- DocumentFragment fragment = doc.createDocumentFragment();
- while (documentElement.getFirstChild() != null) {
- fragment.appendChild(documentElement.getFirstChild());
- }
-
- // log parsed document
- if (log.isTraceEnabled()) {
-
- StringWriter writer = new StringWriter();
-
- writer.write("DataObject:\n");
-
- LSOutput output = domImplLS.createLSOutput();
- output.setCharacterStream(writer);
- output.setEncoding("UTF-8");
- LSSerializer serializer = domImplLS.createLSSerializer();
- serializer.getDomConfig().setParameter("xml-declaration", Boolean.FALSE);
- serializer.write(fragment, output);
-
- log.trace(writer.toString());
- }
-
- return fragment;
-
- }
-
- /**
- * Parses the given <code>inputStream</code> using the given
- * <code>encoding</code> and returns the parsed document.
- *
- * @param inputStream
- * the to-be parsed input
- *
- * @param encoding
- * the encoding to be used for parsing the given
- * <code>inputStream</code>
- *
- * @return the parsed document
- *
- * @throws SLCommandException
- * if parsing the <code>inputStream</code> fails.
- *
- * @throws NullPointerException
- * if <code>inputStram</code> is <code>null</code>
- */
- private Document parseDataObject(InputStream inputStream, String encoding) throws SLCommandException {
-
- LSInput input = domImplLS.createLSInput();
- input.setByteStream(inputStream);
-
- if (encoding != null) {
- input.setEncoding(encoding);
- }
-
- LSParser parser = domImplLS.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
- DOMConfiguration domConfig = parser.getDomConfig();
- SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
- domConfig.setParameter("error-handler", errorHandler);
- domConfig.setParameter("validate", Boolean.FALSE);
-
- Document doc;
- try {
- doc = parser.parse(input);
- } catch (DOMException e) {
- log.info("Existing XML document cannot be parsed.", e);
- throw new SLCommandException(4111);
- } catch (LSException e) {
- log.info("Existing XML document cannot be parsed. ", e);
- throw new SLCommandException(4111);
- }
-
- if (errorHandler.hasErrors()) {
- // log errors
- if (log.isInfoEnabled()) {
- List<String> errorMessages = errorHandler.getErrorMessages();
- StringBuffer sb = new StringBuffer();
- for (String errorMessage : errorMessages) {
- sb.append(" ");
- sb.append(errorMessage);
- }
- log.info("Existing XML document cannot be parsed. " + sb.toString());
- }
- throw new SLCommandException(4111);
- }
-
- return doc;
-
- }
-
-
-}