diff options
Diffstat (limited to 'bkucommon/src/main')
| -rw-r--r-- | bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java | 2078 | ||||
| -rw-r--r-- | bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java | 5 | 
2 files changed, 1095 insertions, 988 deletions
| diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java index ae4918ce..b64306aa 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java @@ -14,98 +14,105 @@  * 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;
 +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.slexceptions.SLCommandException;
 -import at.gv.egiz.bku.slexceptions.SLRequestException;
 -import at.gv.egiz.bku.slexceptions.SLRuntimeException;
 +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.w3._2000._09.xmldsig_.TransformType; +import org.w3._2000._09.xmldsig_.TransformsType; +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.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.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;
 -
 -/**
 - * 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[] {
 +import at.gv.egiz.dom.DOMUtils; +import at.gv.egiz.marshal.NamespacePrefix; +import at.gv.egiz.marshal.NamespacePrefixMapperImpl; +import at.gv.egiz.slbinding.impl.XMLContentType; +import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +/** + * 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" 
 +      "application/xhtml+xml"       };    /** @@ -149,87 +156,87 @@ public class DataObject {      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;
 -  
 -  /**
 -   * 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;
 -  }
 -
 -  /**
 -   * @return the description
 -   */
 -  public String getDescription() {
 -    return description;
 -  }
 +  /** +   * 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; +   +  /** +   * 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; +  } + +  /** +   * @return the description +   */ +  public String getDescription() { +    return description; +  }    public void validateHashDataInput() throws SLViewerException { @@ -293,823 +300,920 @@ public class DataObject {      }    } -  
 -  /**
 -   * 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
 -    
 -  }
 -
 -  /**
 -   * 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 {
 -    
 -    ByteArrayOutputStream redirectedStream = ((at.gv.egiz.slbinding.impl.TransformsInfoType) transformsInfo).getRedirectedStream();
 -    byte[] transformBytes = (redirectedStream != null) ? redirectedStream.toByteArray() : null;
 -    
 -    if (transformBytes != null && transformBytes.length > 0) {
 -
 -      // debug
 -      if (log.isTraceEnabled()) {
 -        StringBuilder sb = new StringBuilder();
 -        sb.append("Trying to parse transforms:\n");
 -        sb.append(new String(transformBytes, Charset.forName("UTF-8")));
 -        log.trace(sb);
 -      }
 -      
 -      DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
 -      LSInput input = domImplLS.createLSInput();
 -      input.setByteStream(new ByteArrayInputStream(transformBytes));
 -
 -      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 documentElement = document.getDocumentElement();
 -      Node adoptedTransforms = ctx.getDocument().adoptNode(documentElement);
 -
 -      DOMCryptoContext context = new DOMCryptoContext();
 -
 -      // unmarshall ds:Transforms
 -      return new XSECTTransforms(context, adoptedTransforms);
 -
 -    } else {
 -      return null;
 -    }
 -    
 -  }
 -  
 -  /**
 -   * 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;
 -    
 -  }
 -
 -
 -}
 +   +  /** +   * 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 +     +  } + +  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; +     +  } + + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java index 8baa0137..9182e824 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java @@ -87,6 +87,8 @@ import at.gv.egiz.bku.utils.urldereferencer.StreamData;  import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;  import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;  import at.gv.egiz.dom.DOMUtils; +import at.gv.egiz.marshal.NamespacePrefix; +import at.gv.egiz.marshal.NamespacePrefixMapperImpl;  import at.gv.egiz.slbinding.impl.XMLContentType;  import at.gv.egiz.stal.STAL;  import at.gv.egiz.xades.QualifyingPropertiesException; @@ -99,6 +101,7 @@ import at.gv.egiz.xades.QualifyingPropertiesFactory;   * @author mcentner   */  public class Signature { +  public static final String XMLDSIG_PREFIX = "dsig";    /**     * Logging facility. @@ -407,7 +410,7 @@ public class Signature {      signContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE); -    signContext.putNamespacePrefix(XMLSignature.XMLNS, "dsig"); +    signContext.putNamespacePrefix(XMLSignature.XMLNS,XMLDSIG_PREFIX);       signContext.setURIDereferencer(new URIDereferncerAdapter(ctx.getDereferencerContext())); | 
