8217878: ENVELOPING XML signature no longer works in JDK 11
authormullan
Tue, 05 Mar 2019 08:24:58 -0500
changeset 53998 d870bb08194a
parent 53997 4ae746de6b86
child 53999 d7852bb72332
8217878: ENVELOPING XML signature no longer works in JDK 11 8218629: XML Digital Signature throws NAMESPACE_ERR exception on OpenJDK 11, works 8/9/10 Summary: Backout and restore previous XML signature marshalling implementation Reviewed-by: weijun
src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java
src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/BaseStructure.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMUtils.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Marshaller.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XmlWriter.java
src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XmlWriterToTree.java
test/jdk/javax/xml/crypto/dsig/GenerationTests.java
test/jdk/javax/xml/crypto/dsig/data/envelope2.xml
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java	Tue Mar 05 08:24:58 2019 -0500
@@ -148,7 +148,8 @@
      * @return String with Base64 encoding
      */
     public static final String encode(BigInteger big) {
-        return encode(getBytes(big, big.bitLength()));
+        byte[] bytes = XMLUtils.getBytes(big, big.bitLength());
+        return XMLUtils.encodeToString(bytes);
     }
 
     /**
@@ -214,9 +215,9 @@
      * @return a decoded BigInteger
      * @throws Base64DecodingException
      */
-    public static BigInteger decodeBigIntegerFromString(String base64str)
-            throws Base64DecodingException {
-        return new BigInteger(1, Base64.decode(base64str));
+    public static final BigInteger decodeBigIntegerFromText(Text text)
+        throws Base64DecodingException {
+        return new BigInteger(1, Base64.decode(text.getData()));
     }
 
     /**
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java	Tue Mar 05 08:24:58 2019 -0500
@@ -28,6 +28,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
+import java.util.Base64;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -443,6 +444,25 @@
         }
     }
 
+    public static String encodeToString(byte[] bytes) {
+        if (ignoreLineBreaks) {
+            return Base64.getEncoder().encodeToString(bytes);
+        }
+        return Base64.getMimeEncoder().encodeToString(bytes);
+    }
+
+    public static byte[] decode(String encodedString) {
+        return Base64.getMimeDecoder().decode(encodedString);
+    }
+
+    public static byte[] decode(byte[] encodedBytes) {
+        return Base64.getMimeDecoder().decode(encodedBytes);
+    }
+
+    public static boolean isIgnoreLineBreaks() {
+        return ignoreLineBreaks;
+    }
+
     /**
      * Method convertNodelistToSet
      *
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,19 +29,23 @@
 import java.security.SignatureException;
 import java.security.spec.AlgorithmParameterSpec;
 import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignedInfo;
 import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.XMLSignatureException;
 import javax.xml.crypto.dsig.XMLSignContext;
 import javax.xml.crypto.dsig.XMLValidateContext;
 import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * An abstract class representing a SignatureMethod. Subclasses implement
  * a specific XML DSig signature algorithm.
  */
-abstract class AbstractDOMSignatureMethod extends BaseStructure
+abstract class AbstractDOMSignatureMethod extends DOMStructure
     implements SignatureMethod {
 
     // denotes the type of signature algorithm
@@ -65,7 +69,7 @@
      *    as the passed in signature is improperly encoded
      * @throws XMLSignatureException if an unexpected error occurs
      */
-    abstract boolean verify(Key key, DOMSignedInfo si, byte[] sig,
+    abstract boolean verify(Key key, SignedInfo si, byte[] sig,
                             XMLValidateContext context)
         throws InvalidKeyException, SignatureException, XMLSignatureException;
 
@@ -83,7 +87,7 @@
      *    the wrong type, or parameters are missing, etc
      * @throws XMLSignatureException if an unexpected error occurs
      */
-    abstract byte[] sign(Key key, DOMSignedInfo si, XMLSignContext context)
+    abstract byte[] sign(Key key, SignedInfo si, XMLSignContext context)
         throws InvalidKeyException, XMLSignatureException;
 
     /**
@@ -101,16 +105,21 @@
      * This method invokes the {@link #marshalParams marshalParams}
      * method to marshal any algorithm-specific parameters.
      */
-    public void marshal(XmlWriter xwriter, String dsPrefix)
+    @Override
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
-        xwriter.writeStartElement(dsPrefix, "SignatureMethod", XMLSignature.XMLNS);
-        xwriter.writeAttribute("", "", "Algorithm", getAlgorithm());
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+
+        Element smElem = DOMUtils.createElement(ownerDoc, "SignatureMethod",
+                                                XMLSignature.XMLNS, dsPrefix);
+        DOMUtils.setAttribute(smElem, "Algorithm", getAlgorithm());
 
         if (getParameterSpec() != null) {
-            marshalParams(xwriter, dsPrefix);
+            marshalParams(smElem, dsPrefix);
         }
-        xwriter.writeEndElement(); // "SignatureMethod"
+
+        parent.appendChild(smElem);
     }
 
     /**
@@ -123,7 +132,7 @@
      * @param paramsPrefix the algorithm parameters prefix to use
      * @throws MarshalException if the parameters cannot be marshalled
      */
-    void marshalParams(XmlWriter xwriter, String paramsPrefix)
+    void marshalParams(Element parent, String paramsPrefix)
         throws MarshalException
     {
         throw new MarshalException("no parameters should " +
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java	Tue Mar 05 08:24:58 2019 -0500
@@ -69,7 +69,6 @@
         return params;
     }
 
-    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -88,7 +87,6 @@
         ownerDoc = DOMUtils.getOwnerDocument(transformElem);
     }
 
-    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java	Tue Mar 05 08:24:58 2019 -0500
@@ -45,7 +45,6 @@
         this.xi = xi;
     }
 
-    @Override
     public XMLSignatureInput getXMLSignatureInput() {
         return xi;
     }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java	Tue Mar 05 08:24:58 2019 -0500
@@ -67,7 +67,6 @@
         return params;
     }
 
-    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -86,7 +85,6 @@
         ownerDoc = DOMUtils.getOwnerDocument(transformElem);
     }
 
-    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
@@ -105,7 +103,6 @@
         ownerDoc = DOMUtils.getOwnerDocument(transformElem);
     }
 
-    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException
     {
@@ -115,7 +112,6 @@
         return transformIt(data, xc, null);
     }
 
-    @Override
     public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
         throws TransformException
     {
@@ -206,7 +202,6 @@
         }
     }
 
-    @Override
     public final boolean isFeatureSupported(String feature) {
         if (feature == null) {
             throw new NullPointerException();
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/BaseStructure.java	Tue Mar 05 13:41:36 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.jcp.xml.dsig.internal.dom;
-
-import javax.xml.crypto.XMLStructure;
-
-import org.w3c.dom.Node;
-
-public abstract class BaseStructure implements XMLStructure {
-
-    /**
-     * Just return the text of the immediate child of a node.
-     *
-     * @param node
-     * @return the text of a Node
-     */
-    public static String textOfNode(Node node) {
-        return node.getFirstChild().getNodeValue();
-    }
-
-    public final boolean isFeatureSupported(String feature) {
-        if (feature == null) {
-            throw new NullPointerException();
-        } else {
-            return false;
-        }
-    }
-
-}
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java	Tue Mar 05 08:24:58 2019 -0500
@@ -48,7 +48,6 @@
     public static final String C14N_11_WITH_COMMENTS
         = "http://www.w3.org/2006/12/xml-c14n11#WithComments";
 
-    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException {
         if (params != null) {
@@ -57,7 +56,6 @@
         }
     }
 
-    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException {
 
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java	Tue Mar 05 08:24:58 2019 -0500
@@ -44,7 +44,6 @@
  */
 public final class DOMCanonicalXMLC14NMethod extends ApacheCanonicalizer {
 
-    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException {
         if (params != null) {
@@ -53,7 +52,6 @@
         }
     }
 
-    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java	Tue Mar 05 08:24:58 2019 -0500
@@ -0,0 +1,101 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ */
+/*
+ * $Id$
+ */
+package org.jcp.xml.dsig.internal.dom;
+
+import java.math.BigInteger;
+import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
+
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * A DOM-based representation of the XML <code>CryptoBinary</code> simple type
+ * as defined in the W3C specification for XML-Signature Syntax and Processing.
+ * The XML Schema Definition is defined as:
+ *
+ * <xmp>
+ * <simpleType name="CryptoBinary">
+ *   <restriction base = "base64Binary">
+ *   </restriction>
+ * </simpleType>
+ * </xmp>
+ *
+ * @author Sean Mullan
+ */
+public final class DOMCryptoBinary extends DOMStructure {
+
+    private final BigInteger bigNum;
+    private final String value;
+
+    /**
+     * Create a <code>DOMCryptoBinary</code> instance from the specified
+     * <code>BigInteger</code>
+     *
+     * @param bigNum the arbitrary-length integer
+     * @throws NullPointerException if <code>bigNum</code> is <code>null</code>
+     */
+    public DOMCryptoBinary(BigInteger bigNum) {
+        if (bigNum == null) {
+            throw new NullPointerException("bigNum is null");
+        }
+        this.bigNum = bigNum;
+        // convert to bitstring
+        byte[] bytes = XMLUtils.getBytes(bigNum, bigNum.bitLength());
+        value = XMLUtils.encodeToString(bytes);
+    }
+
+    /**
+     * Creates a <code>DOMCryptoBinary</code> from a node.
+     *
+     * @param cbNode a CryptoBinary text node
+     * @throws MarshalException if value cannot be decoded (invalid format)
+     */
+    public DOMCryptoBinary(Node cbNode) throws MarshalException {
+        value = cbNode.getNodeValue();
+        try {
+            bigNum = new BigInteger(1, XMLUtils.decode(((Text) cbNode).getData()));
+        } catch (Exception ex) {
+            throw new MarshalException(ex);
+        }
+    }
+
+    /**
+     * Returns the <code>BigInteger</code> that this object contains.
+     *
+     * @return the <code>BigInteger</code> that this object contains
+     */
+    public BigInteger getBigNum() {
+        return bigNum;
+    }
+
+    @Override
+    public void marshal(Node parent, String prefix, DOMCryptoContext context)
+        throws MarshalException {
+        parent.appendChild
+            (DOMUtils.getOwnerDocument(parent).createTextNode(value));
+    }
+}
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,18 +29,21 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.*;
 import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
 
 import java.security.InvalidAlgorithmParameterException;
 import java.security.spec.AlgorithmParameterSpec;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * DOM-based abstract implementation of DigestMethod.
  *
  */
-public abstract class DOMDigestMethod extends BaseStructure
+public abstract class DOMDigestMethod extends DOMStructure
     implements DigestMethod {
 
     static final String SHA224 =
@@ -147,7 +150,6 @@
         }
     }
 
-    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return params;
     }
@@ -175,17 +177,21 @@
      * This method invokes the abstract {@link #marshalParams marshalParams}
      * method to marshal any algorithm-specific parameters.
      */
-    public static void marshal(XmlWriter xwriter, DigestMethod digest, String prefix)
+    @Override
+    public void marshal(Node parent, String prefix, DOMCryptoContext context)
         throws MarshalException
     {
-        xwriter.writeStartElement(prefix, "DigestMethod", XMLSignature.XMLNS);
-        xwriter.writeAttribute("", "", "Algorithm", digest.getAlgorithm());
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+
+        Element dmElem = DOMUtils.createElement(ownerDoc, "DigestMethod",
+                                                XMLSignature.XMLNS, prefix);
+        DOMUtils.setAttribute(dmElem, "Algorithm", getAlgorithm());
 
-        // this is totally over-engineered - nothing implements marshalParams.
-        if (digest.getParameterSpec() != null && digest instanceof DOMDigestMethod) {
-            ( (DOMDigestMethod) digest).marshalParams(xwriter, prefix);
+        if (params != null) {
+            marshalParams(dmElem, prefix);
         }
-        xwriter.writeEndElement(); // "DigestMethod"
+
+        parent.appendChild(dmElem);
     }
 
     @Override
@@ -226,7 +232,7 @@
      * @param the namespace prefix to use
      * @throws MarshalException if the parameters cannot be marshalled
      */
-    void marshalParams(XmlWriter xwriter, String prefix)
+    void marshalParams(Element parent, String prefix)
         throws MarshalException
     {
         throw new MarshalException("no parameters should " +
@@ -248,11 +254,9 @@
         SHA1(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return DigestMethod.SHA1;
         }
-        @Override
         String getMessageDigestAlgorithm() {
             return "SHA-1";
         }
@@ -284,11 +288,9 @@
         SHA256(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return DigestMethod.SHA256;
         }
-        @Override
         String getMessageDigestAlgorithm() {
             return "SHA-256";
         }
@@ -302,11 +304,9 @@
         SHA384(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return SHA384;
         }
-        @Override
         String getMessageDigestAlgorithm() {
             return "SHA-384";
         }
@@ -320,11 +320,9 @@
         SHA512(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return DigestMethod.SHA512;
         }
-        @Override
         String getMessageDigestAlgorithm() {
             return "SHA-512";
         }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java	Tue Mar 05 08:24:58 2019 -0500
@@ -38,7 +38,6 @@
  */
 public final class DOMEnvelopedTransform extends ApacheTransform {
 
-    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException {
         if (params != null) {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java	Tue Mar 05 08:24:58 2019 -0500
@@ -50,7 +50,6 @@
  */
 public final class DOMExcC14NMethod extends ApacheCanonicalizer {
 
-    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException
     {
@@ -63,7 +62,6 @@
         }
     }
 
-    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -109,12 +107,20 @@
             return;
         }
 
-        XmlWriterToTree xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), transformElem);
-
-        String prefix =
-            DOMUtils.getNSPrefix(context, CanonicalizationMethod.EXCLUSIVE);
-        xwriter.writeStartElement(prefix, "InclusiveNamespaces", CanonicalizationMethod.EXCLUSIVE);
-        xwriter.writeNamespace(prefix, CanonicalizationMethod.EXCLUSIVE);
+        String prefix = DOMUtils.getNSPrefix(context,
+                                             CanonicalizationMethod.EXCLUSIVE);
+        Element eElem = DOMUtils.createElement(ownerDoc,
+                                               "InclusiveNamespaces",
+                                               CanonicalizationMethod.EXCLUSIVE,
+                                               prefix);
+        if (prefix == null || prefix.length() == 0) {
+            eElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
+                                 CanonicalizationMethod.EXCLUSIVE);
+        } else {
+            eElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
+                                   "xmlns:" + prefix,
+                                   CanonicalizationMethod.EXCLUSIVE);
+        }
 
         ExcC14NParameterSpec params = (ExcC14NParameterSpec)spec;
         StringBuilder prefixListAttr = new StringBuilder("");
@@ -125,16 +131,15 @@
                 prefixListAttr.append(" ");
             }
         }
-        xwriter.writeAttribute("", "", "PrefixList", prefixListAttr.toString());
+        DOMUtils.setAttribute(eElem, "PrefixList", prefixListAttr.toString());
         this.inclusiveNamespaces = prefixListAttr.toString();
-        xwriter.writeEndElement(); // "InclusiveNamespaces"
+        transformElem.appendChild(eElem);
     }
 
     public String getParamsNSURI() {
         return CanonicalizationMethod.EXCLUSIVE;
     }
 
-    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException
     {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java	Tue Mar 05 08:24:58 2019 -0500
@@ -42,6 +42,7 @@
 import java.security.spec.AlgorithmParameterSpec;
 import javax.crypto.Mac;
 import javax.crypto.SecretKey;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 import org.jcp.xml.dsig.internal.MacOutputStream;
@@ -117,30 +118,32 @@
         }
     }
 
-    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return params;
     }
 
-    @Override
     SignatureMethodParameterSpec unmarshalParams(Element paramsElem)
         throws MarshalException
     {
-        outputLength = Integer.parseInt(textOfNode(paramsElem));
+        outputLength = Integer.parseInt(paramsElem.getFirstChild().getNodeValue());
         outputLengthSet = true;
         LOG.debug("unmarshalled outputLength: {}", outputLength);
         return new HMACParameterSpec(outputLength);
     }
 
-    @Override
-    void marshalParams(XmlWriter xwriter, String prefix)
+    void marshalParams(Element parent, String prefix)
         throws MarshalException
     {
-        xwriter.writeTextElement(prefix, "HMACOutputLength", XMLSignature.XMLNS, String.valueOf(outputLength));
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+        Element hmacElem = DOMUtils.createElement(ownerDoc, "HMACOutputLength",
+                                                  XMLSignature.XMLNS, prefix);
+        hmacElem.appendChild(ownerDoc.createTextNode
+           (String.valueOf(outputLength)));
+
+        parent.appendChild(hmacElem);
     }
 
-    @Override
-    boolean verify(Key key, DOMSignedInfo si, byte[] sig,
+    boolean verify(Key key, SignedInfo si, byte[] sig,
                    XMLValidateContext context)
         throws InvalidKeyException, SignatureException, XMLSignatureException
     {
@@ -162,14 +165,13 @@
                 ("HMACOutputLength must not be less than " + getDigestLength());
         }
         hmac.init(key);
-        si.canonicalize(context, new MacOutputStream(hmac));
+        ((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
         byte[] result = hmac.doFinal();
 
         return MessageDigest.isEqual(sig, result);
     }
 
-    @Override
-    byte[] sign(Key key, DOMSignedInfo si, XMLSignContext context)
+    byte[] sign(Key key, SignedInfo si, XMLSignContext context)
         throws InvalidKeyException, XMLSignatureException
     {
         if (key == null || si == null) {
@@ -190,11 +192,10 @@
                 ("HMACOutputLength must not be less than " + getDigestLength());
         }
         hmac.init(key);
-        si.canonicalize(context, new MacOutputStream(hmac));
+        ((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
         return hmac.doFinal();
     }
 
-    @Override
     boolean paramsEqual(AlgorithmParameterSpec spec) {
         if (getParameterSpec() == spec) {
             return true;
@@ -207,7 +208,6 @@
         return outputLength == ospec.getOutputLength();
     }
 
-    @Override
     Type getAlgorithmType() {
         return Type.HMAC;
     }
@@ -225,15 +225,12 @@
         SHA1(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return SignatureMethod.HMAC_SHA1;
         }
-        @Override
         String getJCAAlgorithm() {
             return "HmacSHA1";
         }
-        @Override
         int getDigestLength() {
             return 160;
         }
@@ -269,15 +266,12 @@
         SHA256(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return HMAC_SHA256;
         }
-        @Override
         String getJCAAlgorithm() {
             return "HmacSHA256";
         }
-        @Override
         int getDigestLength() {
             return 256;
         }
@@ -291,15 +285,12 @@
         SHA384(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return HMAC_SHA384;
         }
-        @Override
         String getJCAAlgorithm() {
             return "HmacSHA384";
         }
-        @Override
         int getDigestLength() {
             return 384;
         }
@@ -313,15 +304,12 @@
         SHA512(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return HMAC_SHA512;
         }
-        @Override
         String getJCAAlgorithm() {
             return "HmacSHA512";
         }
-        @Override
         int getDigestLength() {
             return 512;
         }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java	Tue Mar 05 08:24:58 2019 -0500
@@ -36,10 +36,13 @@
 import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.XMLCryptoContext;
 import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.dom.DOMSignContext;
 import javax.xml.crypto.dsig.keyinfo.KeyInfo;
 
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -47,7 +50,7 @@
  * DOM-based implementation of KeyInfo.
  *
  */
-public final class DOMKeyInfo extends BaseStructure implements KeyInfo {
+public final class DOMKeyInfo extends DOMStructure implements KeyInfo {
 
     private final String id;
     private final List<XMLStructure> keyInfoTypes;
@@ -101,7 +104,14 @@
                       Provider provider)
         throws MarshalException
     {
-        id = DOMUtils.getIdAttributeValue(kiElem, "Id");
+        // get Id attribute, if specified
+        Attr attr = kiElem.getAttributeNodeNS(null, "Id");
+        if (attr != null) {
+            id = attr.getValue();
+            kiElem.setIdAttributeNode(attr, true);
+        } else {
+            id = null;
+        }
 
         // get all children nodes
         List<XMLStructure> content = new ArrayList<>();
@@ -134,17 +144,14 @@
         keyInfoTypes = Collections.unmodifiableList(content);
     }
 
-    @Override
     public String getId() {
         return id;
     }
 
-    @Override
     public List<XMLStructure> getContent() {
         return keyInfoTypes;
     }
 
-    @Override
     public void marshal(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
@@ -155,44 +162,62 @@
             throw new ClassCastException("parent must be of type DOMStructure");
         }
 
-        internalMarshal( (javax.xml.crypto.dom.DOMStructure) parent, context);
-    }
-
-    private void internalMarshal(javax.xml.crypto.dom.DOMStructure parent, XMLCryptoContext context)
-            throws MarshalException {
-        Node pNode = parent.getNode();
+        Node pNode = ((javax.xml.crypto.dom.DOMStructure)parent).getNode();
         String dsPrefix = DOMUtils.getSignaturePrefix(context);
+        Element kiElem = DOMUtils.createElement
+            (DOMUtils.getOwnerDocument(pNode), "KeyInfo",
+             XMLSignature.XMLNS, dsPrefix);
+        if (dsPrefix == null || dsPrefix.length() == 0) {
+            kiElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
+                                  "xmlns", XMLSignature.XMLNS);
+        } else {
+            kiElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
+                                  "xmlns:" + dsPrefix, XMLSignature.XMLNS);
+        }
 
         Node nextSibling = null;
         if (context instanceof DOMSignContext) {
             nextSibling = ((DOMSignContext)context).getNextSibling();
         }
-
-        XmlWriterToTree xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), pNode, nextSibling);
-        marshalInternal(xwriter, this, dsPrefix, context, true);
+        marshal(pNode, kiElem, nextSibling, dsPrefix, (DOMCryptoContext)context);
     }
 
-    public static void marshal(XmlWriter xwriter, KeyInfo ki, String dsPrefix,
-    XMLCryptoContext context) throws MarshalException {
-        marshalInternal(xwriter, ki, dsPrefix, context, false);
+    @Override
+    public void marshal(Node parent, String dsPrefix,
+                        DOMCryptoContext context)
+        throws MarshalException
+    {
+        marshal(parent, null, dsPrefix, context);
     }
 
-    private static void marshalInternal(XmlWriter xwriter, KeyInfo ki,
-        String dsPrefix, XMLCryptoContext context, boolean declareNamespace) throws MarshalException {
+    public void marshal(Node parent, Node nextSibling, String dsPrefix,
+                        DOMCryptoContext context)
+        throws MarshalException
+    {
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+        Element kiElem = DOMUtils.createElement(ownerDoc, "KeyInfo",
+                                                XMLSignature.XMLNS, dsPrefix);
+        marshal(parent, kiElem, nextSibling, dsPrefix, context);
+    }
 
-        xwriter.writeStartElement(dsPrefix, "KeyInfo", XMLSignature.XMLNS);
-        if (declareNamespace) {
-            xwriter.writeNamespace(dsPrefix, XMLSignature.XMLNS);
+    private void marshal(Node parent, Element kiElem, Node nextSibling,
+                         String dsPrefix, DOMCryptoContext context)
+        throws MarshalException
+    {
+        // create and append KeyInfoType elements
+        for (XMLStructure kiType : keyInfoTypes) {
+            if (kiType instanceof DOMStructure) {
+                ((DOMStructure)kiType).marshal(kiElem, dsPrefix, context);
+            } else {
+                DOMUtils.appendChild(kiElem,
+                    ((javax.xml.crypto.dom.DOMStructure)kiType).getNode());
+            }
         }
 
-        xwriter.writeIdAttribute("", "", "Id", ki.getId());
-        // create and append KeyInfoType elements
-        List<XMLStructure> keyInfoTypes = getContent(ki);
-        for (XMLStructure kiType : keyInfoTypes) {
-            xwriter.marshalStructure(kiType, dsPrefix, context);
-        }
+        // append id attribute
+        DOMUtils.setAttributeID(kiElem, "Id", id);
 
-        xwriter.writeEndElement(); // "KeyInfo"
+        parent.insertBefore(kiElem, nextSibling);
     }
 
     @Override
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java	Tue Mar 05 08:24:58 2019 -0500
@@ -31,15 +31,24 @@
 import java.math.BigInteger;
 import java.security.KeyException;
 import java.security.PublicKey;
+import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.RSAPublicKey;
 import java.util.List;
 
-import javax.xml.crypto.*;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.XMLStructure;
 import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.XMLSignature;
-import javax.xml.crypto.dsig.keyinfo.*;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.keyinfo.KeyName;
+import javax.xml.crypto.dsig.keyinfo.KeyValue;
+import javax.xml.crypto.dsig.keyinfo.PGPData;
+import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;
+import javax.xml.crypto.dsig.keyinfo.X509Data;
+import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -53,24 +62,20 @@
 
     public DOMKeyInfoFactory() { }
 
-    @Override
     @SuppressWarnings("rawtypes")
     public KeyInfo newKeyInfo(List content) {
         return newKeyInfo(content, null);
     }
 
-    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public KeyInfo newKeyInfo(List content, String id) {
         return new DOMKeyInfo(content, id);
     }
 
-    @Override
     public KeyName newKeyName(String name) {
         return new DOMKeyName(name);
     }
 
-    @Override
     public KeyValue newKeyValue(PublicKey key)  throws KeyException {
         String algorithm = key.getAlgorithm();
         if ("DSA".equals(algorithm)) {
@@ -84,30 +89,25 @@
         }
     }
 
-    @Override
     public PGPData newPGPData(byte[] keyId) {
         return newPGPData(keyId, null, null);
     }
 
-    @Override
     @SuppressWarnings({ "rawtypes", "unchecked" })
     public PGPData newPGPData(byte[] keyId, byte[] keyPacket, List other) {
         return new DOMPGPData(keyId, keyPacket, other);
     }
 
-    @Override
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     public PGPData newPGPData(byte[] keyPacket, List other) {
         return new DOMPGPData(keyPacket, other);
     }
 
-    @Override
     public RetrievalMethod newRetrievalMethod(String uri) {
         return newRetrievalMethod(uri, null, null);
     }
 
-    @Override
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     public RetrievalMethod newRetrievalMethod(String uri, String type,
         List transforms) {
         if (uri == null) {
@@ -116,8 +116,7 @@
         return new DOMRetrievalMethod(uri, type, transforms);
     }
 
-    @Override
-    @SuppressWarnings("rawtypes")
+    @SuppressWarnings({ "rawtypes" })
     public X509Data newX509Data(List content) {
         return new DOMX509Data(content);
     }
@@ -128,7 +127,6 @@
         return new DOMX509IssuerSerial(issuerName, serialNumber);
     }
 
-    @Override
     public boolean isFeatureSupported(String feature) {
         if (feature == null) {
             throw new NullPointerException();
@@ -137,7 +135,6 @@
         }
     }
 
-    @Override
     public URIDereferencer getURIDereferencer() {
         return DOMURIDereferencer.INSTANCE;
     }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java	Tue Mar 05 08:24:58 2019 -0500
@@ -28,15 +28,20 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.keyinfo.KeyName;
 
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * DOM-based implementation of KeyName.
  *
  */
-public final class DOMKeyName extends BaseStructure implements KeyName {
+public final class DOMKeyName extends DOMStructure implements KeyName {
 
     private final String name;
 
@@ -59,12 +64,23 @@
      * @param knElem a KeyName element
      */
     public DOMKeyName(Element knElem) {
-        name = textOfNode(knElem);
+        name = knElem.getFirstChild().getNodeValue();
+    }
+
+    public String getName() {
+        return name;
     }
 
     @Override
-    public String getName() {
-        return name;
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
+        throws MarshalException
+    {
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+        // prepend namespace prefix, if necessary
+        Element knElem = DOMUtils.createElement(ownerDoc, "KeyName",
+                                                XMLSignature.XMLNS, dsPrefix);
+        knElem.appendChild(ownerDoc.createTextNode(name));
+        parent.appendChild(knElem);
     }
 
     @Override
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,6 +29,7 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.*;
 import javax.xml.crypto.dsig.keyinfo.KeyValue;
 
@@ -53,16 +54,17 @@
 import java.security.spec.KeySpec;
 import java.security.spec.RSAPublicKeySpec;
 import java.util.Arrays;
-import java.util.Base64;
 
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * DOM-based implementation of KeyValue.
  *
  */
-public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure implements KeyValue {
+public abstract class DOMKeyValue<K extends PublicKey> extends DOMStructure implements KeyValue {
 
     private static final String XMLDSIG_11_XMLNS
         = "http://www.w3.org/2009/xmldsig11#";
@@ -102,7 +104,6 @@
         }
     }
 
-    @Override
     public PublicKey getPublicKey() throws KeyException {
         if (publicKey == null) {
             throw new KeyException("can't convert KeyValue to PublicKey");
@@ -111,17 +112,22 @@
         }
     }
 
-    public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
+    @Override
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+
         // create KeyValue element
-        xwriter.writeStartElement(dsPrefix, "KeyValue", XMLSignature.XMLNS);
-        marshalPublicKey(xwriter, publicKey, dsPrefix, context);
-        xwriter.writeEndElement(); // "KeyValue"
+        Element kvElem = DOMUtils.createElement(ownerDoc, "KeyValue",
+                                                XMLSignature.XMLNS, dsPrefix);
+        marshalPublicKey(kvElem, ownerDoc, dsPrefix, context);
+
+        parent.appendChild(kvElem);
     }
 
-    abstract void marshalPublicKey(XmlWriter xwriter, K key, String dsPrefix,
-        XMLCryptoContext context) throws MarshalException;
+    abstract void marshalPublicKey(Node parent, Document doc, String dsPrefix,
+        DOMCryptoContext context) throws MarshalException;
 
     abstract K unmarshalKeyValue(Element kvtElem)
         throws MarshalException;
@@ -162,25 +168,13 @@
 
     public static BigInteger decode(Element elem) throws MarshalException {
         try {
-            String base64str = BaseStructure.textOfNode(elem);
-            return new BigInteger(1, Base64.getMimeDecoder().decode(base64str));
+            String base64str = elem.getFirstChild().getNodeValue();
+            return new BigInteger(1, XMLUtils.decode(base64str));
         } catch (Exception ex) {
             throw new MarshalException(ex);
         }
     }
 
-    public static void writeBase64BigIntegerElement(
-        XmlWriter xwriter, String prefix, String localName, String namespaceURI, BigInteger value
-    ) {
-        byte[] bytes = XMLUtils.getBytes(value, value.bitLength());
-        xwriter.writeTextElement(prefix, localName, namespaceURI, Base64.getMimeEncoder().encodeToString(bytes));
-    }
-
-    public static void marshal(XmlWriter xwriter, BigInteger bigNum) {
-        byte[] bytes = XMLUtils.getBytes(bigNum, bigNum.bitLength());
-        xwriter.writeCharacters(Base64.getMimeEncoder().encodeToString(bytes));
-    }
-
     @Override
     public int hashCode() {
         int result = 17;
@@ -193,25 +187,36 @@
 
     static final class RSA extends DOMKeyValue<RSAPublicKey> {
         // RSAKeyValue CryptoBinaries
+        private DOMCryptoBinary modulus, exponent;
         private KeyFactory rsakf;
 
         RSA(RSAPublicKey key) throws KeyException {
             super(key);
+            RSAPublicKey rkey = key;
+            exponent = new DOMCryptoBinary(rkey.getPublicExponent());
+            modulus = new DOMCryptoBinary(rkey.getModulus());
         }
 
         RSA(Element elem) throws MarshalException {
             super(elem);
         }
 
-        @Override
-        void marshalPublicKey(XmlWriter xwriter, RSAPublicKey publicKey, String dsPrefix,
-            XMLCryptoContext context) throws MarshalException {
-            xwriter.writeStartElement(dsPrefix, "RSAKeyValue", XMLSignature.XMLNS);
-
-            writeBase64BigIntegerElement(xwriter, dsPrefix, "Modulus", XMLSignature.XMLNS, publicKey.getModulus());
-            writeBase64BigIntegerElement(xwriter, dsPrefix, "Exponent", XMLSignature.XMLNS, publicKey.getPublicExponent());
-
-            xwriter.writeEndElement(); // "RSAKeyValue"
+        void marshalPublicKey(Node parent, Document doc, String dsPrefix,
+            DOMCryptoContext context) throws MarshalException {
+            Element rsaElem = DOMUtils.createElement(doc, "RSAKeyValue",
+                                                     XMLSignature.XMLNS,
+                                                     dsPrefix);
+            Element modulusElem = DOMUtils.createElement(doc, "Modulus",
+                                                         XMLSignature.XMLNS,
+                                                         dsPrefix);
+            Element exponentElem = DOMUtils.createElement(doc, "Exponent",
+                                                          XMLSignature.XMLNS,
+                                                          dsPrefix);
+            modulus.marshal(modulusElem, dsPrefix, context);
+            exponent.marshal(exponentElem, dsPrefix, context);
+            rsaElem.appendChild(modulusElem);
+            rsaElem.appendChild(exponentElem);
+            parent.appendChild(rsaElem);
         }
 
         @Override
@@ -241,10 +246,17 @@
 
     static final class DSA extends DOMKeyValue<DSAPublicKey> {
         // DSAKeyValue CryptoBinaries
+        private DOMCryptoBinary p, q, g, y; //, seed, pgen;
         private KeyFactory dsakf;
 
         DSA(DSAPublicKey key) throws KeyException {
             super(key);
+            DSAPublicKey dkey = key;
+            DSAParams params = dkey.getParams();
+            p = new DOMCryptoBinary(params.getP());
+            q = new DOMCryptoBinary(params.getQ());
+            g = new DOMCryptoBinary(params.getG());
+            y = new DOMCryptoBinary(dkey.getY());
         }
 
         DSA(Element elem) throws MarshalException {
@@ -252,21 +264,31 @@
         }
 
         @Override
-        void marshalPublicKey(XmlWriter xwriter, DSAPublicKey publicKey, String dsPrefix,
-                XMLCryptoContext context)
+        void marshalPublicKey(Node parent, Document doc, String dsPrefix,
+                              DOMCryptoContext context)
             throws MarshalException
         {
-            DSAParams params = publicKey.getParams();
-
-            xwriter.writeStartElement(dsPrefix, "DSAKeyValue", XMLSignature.XMLNS);
-
+            Element dsaElem = DOMUtils.createElement(doc, "DSAKeyValue",
+                                                     XMLSignature.XMLNS,
+                                                     dsPrefix);
             // parameters J, Seed & PgenCounter are not included
-            writeBase64BigIntegerElement(xwriter, dsPrefix, "P", XMLSignature.XMLNS, params.getP());
-            writeBase64BigIntegerElement(xwriter, dsPrefix, "Q", XMLSignature.XMLNS, params.getQ());
-            writeBase64BigIntegerElement(xwriter, dsPrefix, "G", XMLSignature.XMLNS, params.getG());
-            writeBase64BigIntegerElement(xwriter, dsPrefix, "Y", XMLSignature.XMLNS, publicKey.getY() );
-
-            xwriter.writeEndElement(); // "DSAKeyValue"
+            Element pElem = DOMUtils.createElement(doc, "P", XMLSignature.XMLNS,
+                                                   dsPrefix);
+            Element qElem = DOMUtils.createElement(doc, "Q", XMLSignature.XMLNS,
+                                                   dsPrefix);
+            Element gElem = DOMUtils.createElement(doc, "G", XMLSignature.XMLNS,
+                                                   dsPrefix);
+            Element yElem = DOMUtils.createElement(doc, "Y", XMLSignature.XMLNS,
+                                                   dsPrefix);
+            p.marshal(pElem, dsPrefix, context);
+            q.marshal(qElem, dsPrefix, context);
+            g.marshal(gElem, dsPrefix, context);
+            y.marshal(yElem, dsPrefix, context);
+            dsaElem.appendChild(pElem);
+            dsaElem.appendChild(qElem);
+            dsaElem.appendChild(gElem);
+            dsaElem.appendChild(yElem);
+            parent.appendChild(dsaElem);
         }
 
         @Override
@@ -316,8 +338,7 @@
     }
 
     static final class EC extends DOMKeyValue<ECPublicKey> {
-
-        // ECKeyValue CryptoBinaries
+     // ECKeyValue CryptoBinaries
         private byte[] ecPublicKey;
         private KeyFactory eckf;
         private ECParameterSpec ecParams;
@@ -460,27 +481,35 @@
         }
 
         @Override
-        void marshalPublicKey(XmlWriter xwriter, ECPublicKey publicKey, String dsPrefix,
-                XMLCryptoContext context)
+        void marshalPublicKey(Node parent, Document doc, String dsPrefix,
+                              DOMCryptoContext context)
             throws MarshalException
         {
             String prefix = DOMUtils.getNSPrefix(context, XMLDSIG_11_XMLNS);
-            xwriter.writeStartElement(prefix, "ECKeyValue", XMLDSIG_11_XMLNS);
-
-            xwriter.writeStartElement(prefix, "NamedCurve", XMLDSIG_11_XMLNS);
-            xwriter.writeNamespace(prefix, XMLDSIG_11_XMLNS);
+            Element ecKeyValueElem = DOMUtils.createElement(doc, "ECKeyValue",
+                                                            XMLDSIG_11_XMLNS,
+                                                            prefix);
+            Element namedCurveElem = DOMUtils.createElement(doc, "NamedCurve",
+                                                            XMLDSIG_11_XMLNS,
+                                                            prefix);
+            Element publicKeyElem = DOMUtils.createElement(doc, "PublicKey",
+                                                           XMLDSIG_11_XMLNS,
+                                                           prefix);
             String oid = getCurveOid(ecParams);
             if (oid == null) {
                 throw new MarshalException("Invalid ECParameterSpec");
             }
-            xwriter.writeAttribute("", "", "URI", "urn:oid:" + oid);
-            xwriter.writeEndElement();
-
-            xwriter.writeStartElement(prefix, "PublicKey", XMLDSIG_11_XMLNS);
-            String encoded = Base64.getMimeEncoder().encodeToString(ecPublicKey);
-            xwriter.writeCharacters(encoded);
-            xwriter.writeEndElement(); // "PublicKey"
-            xwriter.writeEndElement(); // "ECKeyValue"
+            DOMUtils.setAttribute(namedCurveElem, "URI", "urn:oid:" + oid);
+            String qname = (prefix == null || prefix.length() == 0)
+                       ? "xmlns" : "xmlns:" + prefix;
+            namedCurveElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
+                                          qname, XMLDSIG_11_XMLNS);
+            ecKeyValueElem.appendChild(namedCurveElem);
+            String encoded = XMLUtils.encodeToString(ecPublicKey);
+            publicKeyElem.appendChild
+                (DOMUtils.getOwnerDocument(publicKeyElem).createTextNode(encoded));
+            ecKeyValueElem.appendChild(publicKeyElem);
+            parent.appendChild(ecKeyValueElem);
         }
 
         @Override
@@ -526,7 +555,7 @@
 
             try {
                 String content = XMLUtils.getFullTextChildrenFromElement(curElem);
-                ecPoint = decodePoint(Base64.getMimeDecoder().decode(content),
+                ecPoint = decodePoint(XMLUtils.decode(content),
                                       ecParams.getCurve());
             } catch (IOException ioe) {
                 throw new MarshalException("Invalid EC Point", ioe);
@@ -574,21 +603,23 @@
     }
 
     static final class Unknown extends DOMKeyValue<PublicKey> {
-        private XMLStructure externalPublicKey;
+        private javax.xml.crypto.dom.DOMStructure externalPublicKey;
         Unknown(Element elem) throws MarshalException {
             super(elem);
         }
+
         @Override
         PublicKey unmarshalKeyValue(Element kvElem) throws MarshalException {
             externalPublicKey = new javax.xml.crypto.dom.DOMStructure(kvElem);
             return null;
         }
+
         @Override
-        void marshalPublicKey(XmlWriter xwriter, PublicKey publicKey, String dsPrefix,
-                XMLCryptoContext context)
+        void marshalPublicKey(Node parent, Document doc, String dsPrefix,
+                              DOMCryptoContext context)
             throws MarshalException
         {
-            xwriter.marshalStructure(externalPublicKey, dsPrefix, context);
+            parent.appendChild(externalPublicKey.getNode());
         }
     }
 }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,18 +29,21 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.*;
 
 import java.security.Provider;
 import java.util.*;
 
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * DOM-based implementation of Manifest.
  *
  */
-public final class DOMManifest extends BaseStructure implements Manifest {
+public final class DOMManifest extends DOMStructure implements Manifest {
 
     private final List<Reference> references;
     private final String id;
@@ -58,7 +61,7 @@
      * @throws ClassCastException if {@code references} contains any
      *    entries that are not of type {@link Reference}
      */
-    public DOMManifest(List<DOMReference> references, String id) {
+    public DOMManifest(List<? extends Reference> references, String id) {
         if (references == null) {
             throw new NullPointerException("references cannot be null");
         }
@@ -114,7 +117,6 @@
         this.references = Collections.unmodifiableList(refs);
     }
 
-    @Override
     public String getId() {
         return id;
     }
@@ -129,18 +131,21 @@
         return references;
     }
 
-    public static void marshal(XmlWriter xwriter, Manifest manif, String dsPrefix, XMLCryptoContext context)
-    throws MarshalException {
-        xwriter.writeStartElement(dsPrefix, "Manifest", XMLSignature.XMLNS);
-        xwriter.writeIdAttribute("", "", "Id", manif.getId());
+    @Override
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
+        throws MarshalException
+    {
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+        Element manElem = DOMUtils.createElement(ownerDoc, "Manifest",
+                                                 XMLSignature.XMLNS, dsPrefix);
+
+        DOMUtils.setAttributeID(manElem, "Id", id);
 
         // add references
-        @SuppressWarnings("unchecked")
-        List<Reference> references = manif.getReferences();
         for (Reference ref : references) {
-            ((DOMReference)ref).marshal(xwriter, dsPrefix, context);
+            ((DOMReference)ref).marshal(manElem, dsPrefix, context);
         }
-        xwriter.writeEndElement(); // "Manifest"
+        parent.appendChild(manElem);
     }
 
     @Override
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java	Tue Mar 05 08:24:58 2019 -0500
@@ -31,9 +31,11 @@
 import java.util.*;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.keyinfo.PGPData;
 
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -43,7 +45,7 @@
  * DOM-based implementation of PGPData.
  *
  */
-public final class DOMPGPData extends BaseStructure implements PGPData {
+public final class DOMPGPData extends DOMStructure implements PGPData {
 
     private final byte[] keyId;
     private final byte[] keyPacket;
@@ -156,10 +158,10 @@
                 String namespace = childElem.getNamespaceURI();
                 if ("PGPKeyID".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
                     String content = XMLUtils.getFullTextChildrenFromElement(childElem);
-                    pgpKeyId = Base64.getMimeDecoder().decode(content);
+                    pgpKeyId = XMLUtils.decode(content);
                 } else if ("PGPKeyPacket".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
                     String content = XMLUtils.getFullTextChildrenFromElement(childElem);
-                    pgpKeyPacket = Base64.getMimeDecoder().decode(content);
+                    pgpKeyPacket = XMLUtils.decode(content);
                 } else {
                     other.add
                     (new javax.xml.crypto.dom.DOMStructure(childElem));
@@ -172,21 +174,56 @@
         this.externalElements = Collections.unmodifiableList(other);
     }
 
-    @Override
     public byte[] getKeyId() {
         return keyId == null ? null : keyId.clone();
     }
 
-    @Override
     public byte[] getKeyPacket() {
         return keyPacket == null ? null : keyPacket.clone();
     }
 
-    @Override
     public List<XMLStructure> getExternalElements() {
         return externalElements;
     }
 
+    @Override
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
+        throws MarshalException
+    {
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+        Element pdElem = DOMUtils.createElement(ownerDoc, "PGPData",
+                                                XMLSignature.XMLNS, dsPrefix);
+
+        // create and append PGPKeyID element
+        if (keyId != null) {
+            Element keyIdElem = DOMUtils.createElement(ownerDoc, "PGPKeyID",
+                                                       XMLSignature.XMLNS,
+                                                       dsPrefix);
+            keyIdElem.appendChild
+                (ownerDoc.createTextNode(XMLUtils.encodeToString(keyId)));
+            pdElem.appendChild(keyIdElem);
+        }
+
+        // create and append PGPKeyPacket element
+        if (keyPacket != null) {
+            Element keyPktElem = DOMUtils.createElement(ownerDoc,
+                                                        "PGPKeyPacket",
+                                                        XMLSignature.XMLNS,
+                                                        dsPrefix);
+            keyPktElem.appendChild
+                (ownerDoc.createTextNode(XMLUtils.encodeToString(keyPacket)));
+            pdElem.appendChild(keyPktElem);
+        }
+
+        // create and append any elements
+        for (XMLStructure extElem : externalElements) {
+            DOMUtils.appendChild(pdElem, ((javax.xml.crypto.dom.DOMStructure)
+                extElem).getNode());
+        }
+
+        parent.appendChild(pdElem);
+    }
+
     /**
      * We assume packets use the new format packet syntax, as specified in
      * section 4 of RFC 2440.
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java	Tue Mar 05 08:24:58 2019 -0500
@@ -37,6 +37,7 @@
 
 import javax.xml.crypto.*;
 import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dom.DOMURIReference;
 
 import java.io.*;
@@ -46,6 +47,7 @@
 import java.util.*;
 
 import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -54,6 +56,7 @@
 import org.jcp.xml.dsig.internal.DigesterOutputStream;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
 import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 
 /**
  * DOM-based implementation of Reference.
@@ -242,7 +245,7 @@
         // unmarshal DigestValue
         Element dvElem = DOMUtils.getNextSiblingElement(dmElem, "DigestValue", XMLSignature.XMLNS);
         String content = XMLUtils.getFullTextChildrenFromElement(dvElem);
-        this.digestValue = Base64.getMimeDecoder().decode(content);
+        this.digestValue = XMLUtils.decode(content);
 
         // check for extra elements
         if (DOMUtils.getNextSiblingElement(dvElem) != null) {
@@ -252,7 +255,14 @@
 
         // unmarshal attributes
         this.uri = DOMUtils.getAttributeValue(refElem, "URI");
-        this.id = DOMUtils.getIdAttributeValue(refElem, "Id");
+
+        Attr attr = refElem.getAttributeNodeNS(null, "Id");
+        if (attr != null) {
+            this.id = attr.getValue();
+            refElem.setIdAttributeNode(attr, true);
+        } else {
+            this.id = null;
+        }
 
         this.type = DOMUtils.getAttributeValue(refElem, "Type");
         this.here = refElem.getAttributeNodeNS(null, "URI");
@@ -263,76 +273,80 @@
         this.provider = provider;
     }
 
-    @Override
     public DigestMethod getDigestMethod() {
         return digestMethod;
     }
 
-    @Override
     public String getId() {
         return id;
     }
 
-    @Override
     public String getURI() {
         return uri;
     }
 
-    @Override
     public String getType() {
         return type;
     }
 
-    @Override
     public List<Transform> getTransforms() {
         return Collections.unmodifiableList(allTransforms);
     }
 
-    @Override
     public byte[] getDigestValue() {
         return digestValue == null ? null : digestValue.clone();
     }
 
-    @Override
     public byte[] getCalculatedDigestValue() {
         return calcDigestValue == null ? null
                                         : calcDigestValue.clone();
     }
 
     @Override
-    public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
         LOG.debug("Marshalling Reference");
-        xwriter.writeStartElement(dsPrefix, "Reference", XMLSignature.XMLNS);
-        XMLStructure refStruct = xwriter.getCurrentNodeAsStructure();
-        refElem = (Element) ((javax.xml.crypto.dom.DOMStructure) refStruct).getNode();
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
 
+        refElem = DOMUtils.createElement(ownerDoc, "Reference",
+                                         XMLSignature.XMLNS, dsPrefix);
         // set attributes
-        xwriter.writeIdAttribute("", "", "Id", id);
-        here = xwriter.writeAttribute("", "", "URI", uri);
-        xwriter.writeAttribute("", "", "Type", type);
+        DOMUtils.setAttributeID(refElem, "Id", id);
+        DOMUtils.setAttribute(refElem, "URI", uri);
+        DOMUtils.setAttribute(refElem, "Type", type);
 
         // create and append Transforms element
         if (!allTransforms.isEmpty()) {
-            xwriter.writeStartElement(dsPrefix, "Transforms", XMLSignature.XMLNS);
+            Element transformsElem = DOMUtils.createElement(ownerDoc,
+                                                            "Transforms",
+                                                            XMLSignature.XMLNS,
+                                                            dsPrefix);
+            refElem.appendChild(transformsElem);
             for (Transform transform : allTransforms) {
-                xwriter.marshalStructure(transform, dsPrefix, context);
+                ((DOMStructure)transform).marshal(transformsElem,
+                                                  dsPrefix, context);
             }
-            xwriter.writeEndElement(); // "Transforms"
         }
 
         // create and append DigestMethod element
-        DOMDigestMethod.marshal(xwriter, digestMethod, dsPrefix);
+        ((DOMDigestMethod)digestMethod).marshal(refElem, dsPrefix, context);
 
         // create and append DigestValue element
         LOG.debug("Adding digestValueElem");
-        xwriter.writeStartElement(dsPrefix, "DigestValue", XMLSignature.XMLNS);
+        Element digestValueElem = DOMUtils.createElement(ownerDoc,
+                                                         "DigestValue",
+                                                         XMLSignature.XMLNS,
+                                                         dsPrefix);
         if (digestValue != null) {
-            xwriter.writeCharacters(Base64.getMimeEncoder().encodeToString(digestValue));
+            digestValueElem.appendChild
+                (ownerDoc.createTextNode(XMLUtils.encodeToString(digestValue)));
+
         }
-        xwriter.writeEndElement(); // "DigestValue"
-        xwriter.writeEndElement(); // "Reference"
+        refElem.appendChild(digestValueElem);
+
+        parent.appendChild(refElem);
+        here = refElem.getAttributeNodeNS(null, "URI");
     }
 
     public void digest(XMLSignContext signContext)
@@ -347,7 +361,7 @@
         digestValue = transform(data, signContext);
 
         // insert digestValue into DigestValue element
-        String encodedDV = Base64.getMimeEncoder().encodeToString(digestValue);
+        String encodedDV = XMLUtils.encodeToString(digestValue);
         LOG.debug("Reference object uri = {}", uri);
         Element digestElem = DOMUtils.getLastChildElement(refElem);
         if (digestElem == null) {
@@ -361,7 +375,6 @@
         LOG.debug("Reference digesting completed");
     }
 
-    @Override
     public boolean validate(XMLValidateContext validateContext)
         throws XMLSignatureException
     {
@@ -375,8 +388,8 @@
         calcDigestValue = transform(data, validateContext);
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Expected digest: " + Base64.getMimeEncoder().encodeToString(digestValue));
-            LOG.debug("Actual digest: " + Base64.getMimeEncoder().encodeToString(calcDigestValue));
+            LOG.debug("Expected digest: " + XMLUtils.encodeToString(digestValue));
+            LOG.debug("Actual digest: " + XMLUtils.encodeToString(calcDigestValue));
         }
 
         validationStatus = Arrays.equals(digestValue, calcDigestValue);
@@ -384,12 +397,10 @@
         return validationStatus;
     }
 
-    @Override
     public Data getDereferencedData() {
         return derefData;
     }
 
-    @Override
     public InputStream getDigestInputStream() {
         return dis;
     }
@@ -516,8 +527,8 @@
                     } else {
                         transformsElem = DOMUtils.getFirstChildElement(refElem);
                     }
-                    XmlWriter xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), transformsElem);
-                    t.marshal(xwriter, dsPrefix, context);
+                    t.marshal(transformsElem, dsPrefix,
+                              (DOMCryptoContext)context);
                     allTransforms.add(t);
                     xi.updateOutputStream(os, true);
                 } else {
@@ -550,7 +561,6 @@
         }
     }
 
-    @Override
     public Node getHere() {
         return here;
     }
@@ -614,7 +624,6 @@
                 try {
                     final Set<Node> s = xsi.getNodeSet();
                     return new NodeSetData<Node>() {
-                        @Override
                         public Iterator<Node> iterator() { return s.iterator(); }
                     };
                 } catch (Exception e) {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java	Tue Mar 05 08:24:58 2019 -0500
@@ -52,6 +52,7 @@
 import javax.xml.crypto.URIReferenceException;
 import javax.xml.crypto.XMLCryptoContext;
 import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dom.DOMURIReference;
 import javax.xml.crypto.dsig.Transform;
 import javax.xml.crypto.dsig.XMLSignature;
@@ -179,50 +180,53 @@
         }
     }
 
-    @Override
     public String getURI() {
         return uri;
     }
 
-    @Override
     public String getType() {
         return type;
     }
 
-    @Override
     public List<Transform> getTransforms() {
         return transforms;
     }
 
     @Override
-    public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
-        xwriter.writeStartElement(dsPrefix, "RetrievalMethod", XMLSignature.XMLNS);
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+        Element rmElem = DOMUtils.createElement(ownerDoc, "RetrievalMethod",
+                                                XMLSignature.XMLNS, dsPrefix);
 
-        // TODO - see whether it is important to capture the "here" attribute as part of the
-        // marshalling - do any of the tests fail?
         // add URI and Type attributes
-        here = xwriter.writeAttribute("", "", "URI", uri);
-        xwriter.writeAttribute("", "", "Type", type);
+        DOMUtils.setAttribute(rmElem, "URI", uri);
+        DOMUtils.setAttribute(rmElem, "Type", type);
 
         // add Transforms elements
         if (!transforms.isEmpty()) {
-            xwriter.writeStartElement(dsPrefix, "Transforms", XMLSignature.XMLNS);
+            Element transformsElem = DOMUtils.createElement(ownerDoc,
+                                                            "Transforms",
+                                                            XMLSignature.XMLNS,
+                                                            dsPrefix);
+            rmElem.appendChild(transformsElem);
             for (Transform transform : transforms) {
-                ((DOMTransform)transform).marshal(xwriter, dsPrefix, context);
+                ((DOMTransform)transform).marshal(transformsElem,
+                                                   dsPrefix, context);
             }
-            xwriter.writeEndElement(); // "Transforms"
         }
-        xwriter.writeEndElement(); // "RetrievalMethod"
+
+        parent.appendChild(rmElem);
+
+        // save here node
+        here = rmElem.getAttributeNodeNS(null, "URI");
     }
 
-    @Override
     public Node getHere() {
         return here;
     }
 
-    @Override
     public Data dereference(XMLCryptoContext context)
         throws URIReferenceException
     {
@@ -244,7 +248,7 @@
         // pass dereferenced data through Transforms
         try {
             for (Transform transform : transforms) {
-                data = transform.transform(data, context);
+                data = ((DOMTransform)transform).transform(data, context);
             }
         } catch (Exception e) {
             throw new URIReferenceException(e);
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java	Tue Mar 05 08:24:58 2019 -0500
@@ -224,7 +224,6 @@
         }
     }
 
-    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return params;
     }
@@ -246,8 +245,7 @@
             : Signature.getInstance(getJCAAlgorithm(), p);
     }
 
-    @Override
-    boolean verify(Key key, DOMSignedInfo si, byte[] sig,
+    boolean verify(Key key, SignedInfo si, byte[] sig,
                    XMLValidateContext context)
         throws InvalidKeyException, SignatureException, XMLSignatureException
     {
@@ -276,7 +274,7 @@
 
         byte[] s;
         try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
-            si.canonicalize(context, outputStream);
+            ((DOMSignedInfo)si).canonicalize(context, outputStream);
             // Do any necessary format conversions
             s = preVerifyFormat(key, sig);
         } catch (IOException ioe) {
@@ -314,8 +312,7 @@
         }
     }
 
-    @Override
-    byte[] sign(Key key, DOMSignedInfo si, XMLSignContext context)
+    byte[] sign(Key key, SignedInfo si, XMLSignContext context)
         throws InvalidKeyException, XMLSignatureException
     {
         if (key == null || si == null) {
@@ -341,7 +338,7 @@
         LOG.debug("JCA Algorithm: {}", getJCAAlgorithm());
 
         try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
-            si.canonicalize(context, outputStream);
+            ((DOMSignedInfo)si).canonicalize(context, outputStream);
             // Return signature with any necessary format conversions
             return postSignFormat(key, signature.sign());
         } catch (SignatureException | IOException ex){
@@ -570,15 +567,12 @@
         SHA224withRSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return RSA_SHA224;
         }
-        @Override
         String getJCAAlgorithm() {
             return "SHA224withRSA";
         }
-        @Override
         Type getAlgorithmType() {
             return Type.RSA;
         }
@@ -592,15 +586,12 @@
         SHA256withRSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return RSA_SHA256;
         }
-        @Override
         String getJCAAlgorithm() {
             return "SHA256withRSA";
         }
-        @Override
         Type getAlgorithmType() {
             return Type.RSA;
         }
@@ -614,15 +605,12 @@
         SHA384withRSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return RSA_SHA384;
         }
-        @Override
         String getJCAAlgorithm() {
             return "SHA384withRSA";
         }
-        @Override
         Type getAlgorithmType() {
             return Type.RSA;
         }
@@ -636,15 +624,12 @@
         SHA512withRSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return RSA_SHA512;
         }
-        @Override
         String getJCAAlgorithm() {
             return "SHA512withRSA";
         }
-        @Override
         Type getAlgorithmType() {
             return Type.RSA;
         }
@@ -857,18 +842,15 @@
         SHA1withDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return SignatureMethod.DSA_SHA1;
         }
-        @Override
         String getJCAAlgorithm() {
             return "SHA1withDSAinP1363Format";
         }
         String getJCAFallbackAlgorithm() {
             return "SHA1withDSA";
         }
-        @Override
         Type getAlgorithmType() {
             return Type.DSA;
         }
@@ -904,18 +886,15 @@
         SHA1withECDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return ECDSA_SHA1;
         }
-        @Override
         String getJCAAlgorithm() {
             return "SHA1withECDSAinP1363Format";
         }
         String getJCAFallbackAlgorithm() {
             return "SHA1withECDSA";
         }
-        @Override
         Type getAlgorithmType() {
             return Type.ECDSA;
         }
@@ -954,18 +933,15 @@
         SHA256withECDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return ECDSA_SHA256;
         }
-        @Override
         String getJCAAlgorithm() {
             return "SHA256withECDSAinP1363Format";
         }
         String getJCAFallbackAlgorithm() {
             return "SHA256withECDSA";
         }
-        @Override
         Type getAlgorithmType() {
             return Type.ECDSA;
         }
@@ -979,18 +955,15 @@
         SHA384withECDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return ECDSA_SHA384;
         }
-        @Override
         String getJCAAlgorithm() {
             return "SHA384withECDSAinP1363Format";
         }
         String getJCAFallbackAlgorithm() {
             return "SHA384withECDSA";
         }
-        @Override
         Type getAlgorithmType() {
             return Type.ECDSA;
         }
@@ -1004,18 +977,15 @@
         SHA512withECDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
-        @Override
         public String getAlgorithm() {
             return ECDSA_SHA512;
         }
-        @Override
         String getJCAAlgorithm() {
             return "SHA512withECDSAinP1363Format";
         }
         String getJCAFallbackAlgorithm() {
             return "SHA512withECDSA";
         }
-        @Override
         Type getAlgorithmType() {
             return Type.ECDSA;
         }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,10 +29,13 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.*;
 
 import java.util.*;
 
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -40,7 +43,7 @@
  * DOM-based implementation of SignatureProperties.
  *
  */
-public final class DOMSignatureProperties extends BaseStructure
+public final class DOMSignatureProperties extends DOMStructure
     implements SignatureProperties {
 
     private final String id;
@@ -58,7 +61,7 @@
      * @throws IllegalArgumentException if {@code properties} is empty
      * @throws NullPointerException if {@code properties}
      */
-    public DOMSignatureProperties(List<DOMSignatureProperty> properties,
+    public DOMSignatureProperties(List<? extends SignatureProperty> properties,
                                   String id)
     {
         if (properties == null) {
@@ -88,7 +91,13 @@
         throws MarshalException
     {
         // unmarshal attributes
-        id = DOMUtils.getIdAttributeValue(propsElem, "Id");
+        Attr attr = propsElem.getAttributeNodeNS(null, "Id");
+        if (attr != null) {
+            id = attr.getValue();
+            propsElem.setIdAttributeNode(attr, true);
+        } else {
+            id = null;
+        }
 
         List<SignatureProperty> newProperties = new ArrayList<>();
         Node firstChild = propsElem.getFirstChild();
@@ -111,32 +120,34 @@
         }
     }
 
-    @Override
     public List<SignatureProperty> getProperties() {
         return properties;
     }
 
-    @Override
     public String getId() {
         return id;
     }
 
-    public static void marshal(XmlWriter xwriter, SignatureProperties sigProps, String dsPrefix, XMLCryptoContext context)
+    @Override
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
-        xwriter.writeStartElement(dsPrefix, "SignatureProperties", XMLSignature.XMLNS);
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+        Element propsElem = DOMUtils.createElement(ownerDoc,
+                                                   "SignatureProperties",
+                                                   XMLSignature.XMLNS,
+                                                   dsPrefix);
 
         // set attributes
-        xwriter.writeIdAttribute("", "", "Id", sigProps.getId());
+        DOMUtils.setAttributeID(propsElem, "Id", id);
 
         // create and append any properties
-        @SuppressWarnings("unchecked")
-        List<SignatureProperty> properties = sigProps.getProperties();
         for (SignatureProperty property : properties) {
-            DOMSignatureProperty.marshal(xwriter, property, dsPrefix, context);
+            ((DOMSignatureProperty)property).marshal(propsElem, dsPrefix,
+                                                     context);
         }
 
-        xwriter.writeEndElement(); // "SignatureProperties"
+        parent.appendChild(propsElem);
     }
 
     @Override
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,10 +29,13 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.*;
 
 import java.util.*;
 
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -40,7 +43,7 @@
  * DOM-based implementation of SignatureProperty.
  *
  */
-public final class DOMSignatureProperty extends BaseStructure
+public final class DOMSignatureProperty extends DOMStructure
     implements SignatureProperty {
 
     private final String id;
@@ -96,7 +99,13 @@
         if (target == null) {
             throw new MarshalException("target cannot be null");
         }
-        id = DOMUtils.getIdAttributeValue(propElem, "Id");
+        Attr attr = propElem.getAttributeNodeNS(null, "Id");
+        if (attr != null) {
+            id = attr.getValue();
+            propElem.setIdAttributeNode(attr, true);
+        } else {
+            id = null;
+        }
 
         List<XMLStructure> newContent = new ArrayList<>();
         Node firstChild = propElem.getFirstChild();
@@ -111,37 +120,37 @@
         }
     }
 
-    @Override
     public List<XMLStructure> getContent() {
         return content;
     }
 
-    @Override
     public String getId() {
         return id;
     }
 
-    @Override
     public String getTarget() {
         return target;
     }
 
-    public static void marshal(XmlWriter xwriter, SignatureProperty sigProp, String dsPrefix, XMLCryptoContext context)
+    @Override
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
-        xwriter.writeStartElement(dsPrefix, "SignatureProperty", XMLSignature.XMLNS);
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+        Element propElem = DOMUtils.createElement(ownerDoc, "SignatureProperty",
+                                                  XMLSignature.XMLNS, dsPrefix);
 
         // set attributes
-        xwriter.writeIdAttribute("", "", "Id", sigProp.getId());
-        xwriter.writeAttribute("", "", "Target", sigProp.getTarget());
+        DOMUtils.setAttributeID(propElem, "Id", id);
+        DOMUtils.setAttribute(propElem, "Target", target);
 
         // create and append any elements and mixed content
-        List<XMLStructure> content = getContent(sigProp);
         for (XMLStructure property : content) {
-            xwriter.marshalStructure(property, dsPrefix, context);
+            DOMUtils.appendChild(propElem,
+                ((javax.xml.crypto.dom.DOMStructure)property).getNode());
         }
 
-        xwriter.writeEndElement(); // "SignatureProperty"
+        parent.appendChild(propElem);
     }
 
     @Override
@@ -176,10 +185,6 @@
         return result;
     }
 
-    @SuppressWarnings("unchecked")
-    private static List<XMLStructure> getContent(SignatureProperty prop) {
-        return prop.getContent();
-    }
     private boolean equalsContent(List<XMLStructure> otherContent) {
         int osize = otherContent.size();
         if (content.size() != osize) {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,6 +29,7 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.*;
 
 import java.io.ByteArrayInputStream;
@@ -39,8 +40,11 @@
 import java.security.Provider;
 import java.util.*;
 
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 
 /**
  * DOM-based implementation of SignedInfo.
@@ -55,6 +59,7 @@
     private CanonicalizationMethod canonicalizationMethod;
     private SignatureMethod signatureMethod;
     private String id;
+    private Document ownerDoc;
     private Element localSiElem;
     private InputStream canonData;
 
@@ -123,6 +128,7 @@
     public DOMSignedInfo(Element siElem, XMLCryptoContext context, Provider provider)
         throws MarshalException {
         localSiElem = siElem;
+        ownerDoc = siElem.getOwnerDocument();
 
         // get Id attribute, if specified
         id = DOMUtils.getAttributeValue(siElem, "Id");
@@ -175,27 +181,22 @@
         references = Collections.unmodifiableList(refList);
     }
 
-    @Override
     public CanonicalizationMethod getCanonicalizationMethod() {
         return canonicalizationMethod;
     }
 
-    @Override
     public SignatureMethod getSignatureMethod() {
         return signatureMethod;
     }
 
-    @Override
     public String getId() {
         return id;
     }
 
-    @Override
     public List<Reference> getReferences() {
         return references;
     }
 
-    @Override
     public InputStream getCanonicalizedData() {
         return canonData;
     }
@@ -223,7 +224,7 @@
                     sb.append((char)signedInfoBytes[i]);
                 }
                 LOG.debug(sb.toString());
-                LOG.debug("Data to be signed/verified:" + Base64.getMimeEncoder().encodeToString(signedInfoBytes));
+                LOG.debug("Data to be signed/verified:" + XMLUtils.encodeToString(signedInfoBytes));
             }
 
             this.canonData = new ByteArrayInputStream(signedInfoBytes);
@@ -236,32 +237,31 @@
     }
 
     @Override
-    public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
-        xwriter.writeStartElement(dsPrefix, "SignedInfo", XMLSignature.XMLNS);
-        XMLStructure siStruct = xwriter.getCurrentNodeAsStructure();
-        localSiElem = (Element) ((javax.xml.crypto.dom.DOMStructure) siStruct).getNode();
-
-        // append Id attribute
-        xwriter.writeIdAttribute("", "", "Id", id);
+        ownerDoc = DOMUtils.getOwnerDocument(parent);
+        Element siElem = DOMUtils.createElement(ownerDoc, "SignedInfo",
+                                                XMLSignature.XMLNS, dsPrefix);
 
         // create and append CanonicalizationMethod element
         DOMCanonicalizationMethod dcm =
             (DOMCanonicalizationMethod)canonicalizationMethod;
-        dcm.marshal(xwriter, dsPrefix, context);
+        dcm.marshal(siElem, dsPrefix, context);
 
         // create and append SignatureMethod element
-        ((AbstractDOMSignatureMethod)signatureMethod).marshal(xwriter, dsPrefix);
+        ((DOMStructure)signatureMethod).marshal(siElem, dsPrefix, context);
 
         // create and append Reference elements
         for (Reference reference : references) {
-            // TODO - either suppress warning here, or figure out how to get rid of the cast.
-            DOMReference domRef = (DOMReference)reference;
-            domRef.marshal(xwriter, dsPrefix, context);
+            ((DOMReference)reference).marshal(siElem, dsPrefix, context);
         }
 
-        xwriter.writeEndElement(); // "SignedInfo"
+        // append Id attribute
+        DOMUtils.setAttributeID(siElem, "Id", id);
+
+        parent.appendChild(siElem);
+        localSiElem = siElem;
     }
 
     @Override
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,13 +29,24 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.MarshalException;
-import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import org.w3c.dom.Node;
 
 /**
  * DOM-based abstract implementation of XMLStructure.
  *
  */
-public abstract class DOMStructure extends BaseStructure {
+public abstract class DOMStructure implements XMLStructure {
 
-    public abstract void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context) throws MarshalException;
+    public final boolean isFeatureSupported(String feature) {
+        if (feature == null) {
+            throw new NullPointerException();
+        } else {
+            return false;
+        }
+    }
+
+    public abstract void marshal(Node parent, String dsPrefix,
+        DOMCryptoContext context) throws MarshalException;
 }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java	Tue Mar 05 08:24:58 2019 -0500
@@ -82,7 +82,6 @@
             this.withComments = !excludeComments;
         }
 
-        @Override
         public boolean hasNext() {
             if (nodeSet == null) {
                 nodeSet = dereferenceSameDocumentURI(root);
@@ -91,7 +90,6 @@
             return li.hasNext();
         }
 
-        @Override
         public Node next() {
             if (nodeSet == null) {
                 nodeSet = dereferenceSameDocumentURI(root);
@@ -104,7 +102,6 @@
             }
         }
 
-        @Override
         public void remove() {
             throw new UnsupportedOperationException();
         }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java	Tue Mar 05 08:24:58 2019 -0500
@@ -37,12 +37,14 @@
 import javax.xml.crypto.Data;
 import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.Transform;
 import javax.xml.crypto.dsig.TransformException;
 import javax.xml.crypto.dsig.TransformService;
 import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.dom.DOMSignContext;
 
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -50,7 +52,7 @@
  * DOM-based abstract implementation of Transform.
  *
  */
-public class DOMTransform extends BaseStructure implements Transform {
+public class DOMTransform extends DOMStructure implements Transform {
 
     protected TransformService spi;
 
@@ -74,6 +76,7 @@
         throws MarshalException
     {
         String algorithm = DOMUtils.getAttributeValue(transElem, "Algorithm");
+
         if (provider == null) {
             try {
                 spi = TransformService.getInstance(algorithm, "DOM");
@@ -98,12 +101,10 @@
         }
     }
 
-    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return spi.getParameterSpec();
     }
 
-    @Override
     public final String getAlgorithm() {
         return spi.getAlgorithm();
     }
@@ -111,18 +112,29 @@
     /**
      * This method marshals any algorithm-specific parameters.
      */
-    public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
+    @Override
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
-        String parentLocalName = xwriter.getCurrentLocalName();
-        String localName = "Transforms".equals(parentLocalName) ? "Transform" : "CanonicalizationMethod";
-        xwriter.writeStartElement(dsPrefix, localName, XMLSignature.XMLNS);
-        xwriter.writeAttribute("", "", "Algorithm", getAlgorithm());
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
 
-        javax.xml.crypto.XMLStructure xmlStruct = xwriter.getCurrentNodeAsStructure();
-        spi.marshalParams(xmlStruct, context);
+        Element transformElem = null;
+        if (parent.getLocalName().equals("Transforms")) {
+            transformElem = DOMUtils.createElement(ownerDoc, "Transform",
+                                                   XMLSignature.XMLNS,
+                                                   dsPrefix);
+        } else {
+            transformElem = DOMUtils.createElement(ownerDoc,
+                                                   "CanonicalizationMethod",
+                                                   XMLSignature.XMLNS,
+                                                   dsPrefix);
+        }
+        DOMUtils.setAttribute(transformElem, "Algorithm", getAlgorithm());
 
-        xwriter.writeEndElement(); // "Transforms" or "CanonicalizationMethod"
+        spi.marshalParams(new javax.xml.crypto.dom.DOMStructure(transformElem),
+                          context);
+
+        parent.appendChild(transformElem);
     }
 
     /**
@@ -136,7 +148,6 @@
      * @throws XMLSignatureException if an unexpected error occurs while
      *    executing the transform
      */
-    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException
     {
@@ -156,7 +167,6 @@
      * @throws XMLSignatureException if an unexpected error occurs while
      *    executing the transform
      */
-    @Override
     public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
         throws TransformException
     {
@@ -210,9 +220,8 @@
     Data transform(Data data, XMLCryptoContext xc, DOMSignContext context)
         throws MarshalException, TransformException
     {
-        Node parent = context.getParent();
-        XmlWriter xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), parent);
-        marshal(xwriter, DOMUtils.getSignaturePrefix(context), context);
+        marshal(context.getParent(),
+                DOMUtils.getSignaturePrefix(context), context);
         return transform(data, xc);
     }
 }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java	Tue Mar 05 08:24:58 2019 -0500
@@ -54,7 +54,6 @@
         Init.init();
     }
 
-    @Override
     public Data dereference(URIReference uriRef, XMLCryptoContext context)
         throws URIReferenceException {
 
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMUtils.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMUtils.java	Tue Mar 05 08:24:58 2019 -0500
@@ -92,7 +92,9 @@
     public static Element createElement(Document doc, String tag,
                                         String nsURI, String prefix)
     {
-        return doc.createElementNS(nsURI, getQNameString(prefix, tag));
+        String qName = (prefix == null || prefix.length() == 0)
+                       ? tag : prefix + ":" + tag;
+        return doc.createElementNS(nsURI, qName);
     }
 
     /**
@@ -335,25 +337,20 @@
             this.nl = nl;
         }
 
-        @Override
         public int size() { return nl.getLength(); }
-        @Override
         public Iterator<Node> iterator() {
             return new Iterator<Node>() {
                 private int index;
 
-                @Override
                 public void remove() {
                     throw new UnsupportedOperationException();
                 }
-                @Override
                 public Node next() {
                     if (!hasNext()) {
                         throw new NoSuchElementException();
                     }
                     return nl.item(index++);
                 }
-                @Override
                 public boolean hasNext() {
                     return index < nl.getLength();
                 }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java	Tue Mar 05 08:24:58 2019 -0500
@@ -34,10 +34,13 @@
 import java.util.*;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.*;
 import javax.xml.crypto.dsig.keyinfo.X509Data;
+import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
 import javax.security.auth.x500.X500Principal;
 
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -48,7 +51,7 @@
  *
  */
 //@@@ check for illegal combinations of data violating MUSTs in W3c spec
-public final class DOMX509Data extends BaseStructure implements X509Data {
+public final class DOMX509Data extends DOMStructure implements X509Data {
 
     private final List<Object> content;
     private CertificateFactory cf;
@@ -113,7 +116,7 @@
                     newContent.add(childElem.getFirstChild().getNodeValue());
                 } else if ("X509SKI".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
                     String content = XMLUtils.getFullTextChildrenFromElement(childElem);
-                    newContent.add(Base64.getMimeDecoder().decode(content));
+                    newContent.add(XMLUtils.decode(content));
                 } else if ("X509CRL".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
                     newContent.add(unmarshalX509CRL(childElem));
                 } else {
@@ -125,68 +128,89 @@
         this.content = Collections.unmodifiableList(newContent);
     }
 
-    @Override
     public List<Object> getContent() {
         return content;
     }
 
-    public static void marshal(XmlWriter xwriter, X509Data x509Data, String dsPrefix, XMLCryptoContext context)
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
-        xwriter.writeStartElement(dsPrefix, "X509Data", XMLSignature.XMLNS);
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+        Element xdElem = DOMUtils.createElement(ownerDoc, "X509Data",
+                                                XMLSignature.XMLNS, dsPrefix);
 
-        List<?> content = x509Data.getContent();
         // append children and preserve order
         for (int i = 0, size = content.size(); i < size; i++) {
             Object object = content.get(i);
             if (object instanceof X509Certificate) {
-                marshalCert(xwriter, (X509Certificate) object, dsPrefix);
+                marshalCert((X509Certificate)object,xdElem,ownerDoc,dsPrefix);
             } else if (object instanceof XMLStructure) {
-                xwriter.marshalStructure((XMLStructure) object, dsPrefix, context);
+                if (object instanceof X509IssuerSerial) {
+                    ((DOMX509IssuerSerial)object).marshal
+                        (xdElem, dsPrefix, context);
+                } else {
+                    javax.xml.crypto.dom.DOMStructure domContent =
+                        (javax.xml.crypto.dom.DOMStructure)object;
+                    DOMUtils.appendChild(xdElem, domContent.getNode());
+                }
             } else if (object instanceof byte[]) {
-                marshalSKI(xwriter, (byte[]) object, dsPrefix);
+                marshalSKI((byte[])object, xdElem, ownerDoc, dsPrefix);
             } else if (object instanceof String) {
-                marshalSubjectName(xwriter, (String) object, dsPrefix);
+                marshalSubjectName((String)object, xdElem, ownerDoc,dsPrefix);
             } else if (object instanceof X509CRL) {
-                marshalCRL(xwriter, (X509CRL) object, dsPrefix);
+                marshalCRL((X509CRL)object, xdElem, ownerDoc, dsPrefix);
             }
         }
-        xwriter.writeEndElement(); // "X509Data"
+
+        parent.appendChild(xdElem);
     }
 
-    private static void marshalSKI(XmlWriter xwriter, byte[] skid, String dsPrefix)
+    private void marshalSKI(byte[] skid, Node parent, Document doc,
+                            String dsPrefix)
     {
-        xwriter.writeTextElement(dsPrefix, "X509SKI", XMLSignature.XMLNS,
-                                 Base64.getMimeEncoder().encodeToString(skid));
+        Element skidElem = DOMUtils.createElement(doc, "X509SKI",
+                                                  XMLSignature.XMLNS, dsPrefix);
+        skidElem.appendChild(doc.createTextNode(XMLUtils.encodeToString(skid)));
+        parent.appendChild(skidElem);
     }
 
-    private static void marshalSubjectName(XmlWriter xwriter, String name, String dsPrefix)
+    private void marshalSubjectName(String name, Node parent, Document doc,
+                                    String dsPrefix)
     {
-        xwriter.writeTextElement(dsPrefix, "X509SubjectName", XMLSignature.XMLNS, name);
+        Element snElem = DOMUtils.createElement(doc, "X509SubjectName",
+                                                XMLSignature.XMLNS, dsPrefix);
+        snElem.appendChild(doc.createTextNode(name));
+        parent.appendChild(snElem);
     }
 
-    private static void marshalCert(XmlWriter xwriter, X509Certificate cert, String dsPrefix)
+    private void marshalCert(X509Certificate cert, Node parent, Document doc,
+                             String dsPrefix)
         throws MarshalException
     {
+        Element certElem = DOMUtils.createElement(doc, "X509Certificate",
+                                                  XMLSignature.XMLNS, dsPrefix);
         try {
-            byte[] encoded = cert.getEncoded();
-            xwriter.writeTextElement(dsPrefix, "X509Certificate", XMLSignature.XMLNS,
-                                     Base64.getMimeEncoder().encodeToString(encoded));
+            certElem.appendChild(doc.createTextNode
+                                 (XMLUtils.encodeToString(cert.getEncoded())));
         } catch (CertificateEncodingException e) {
             throw new MarshalException("Error encoding X509Certificate", e);
         }
+        parent.appendChild(certElem);
     }
 
-    private static void marshalCRL(XmlWriter xwriter, X509CRL crl, String dsPrefix)
+    private void marshalCRL(X509CRL crl, Node parent, Document doc,
+                            String dsPrefix)
         throws MarshalException
     {
+        Element crlElem = DOMUtils.createElement(doc, "X509CRL",
+                                                 XMLSignature.XMLNS, dsPrefix);
         try {
-            byte[] encoded = crl.getEncoded();
-            xwriter.writeTextElement(dsPrefix, "X509CRL", XMLSignature.XMLNS,
-                                     Base64.getMimeEncoder().encodeToString(encoded));
+            crlElem.appendChild(doc.createTextNode
+                                (XMLUtils.encodeToString(crl.getEncoded())));
         } catch (CRLException e) {
             throw new MarshalException("Error encoding X509CRL", e);
         }
+        parent.appendChild(crlElem);
     }
 
     private X509Certificate unmarshalX509Certificate(Element elem)
@@ -218,7 +242,7 @@
                 cf = CertificateFactory.getInstance("X.509");
             }
             String content = XMLUtils.getFullTextChildrenFromElement(elem);
-            return new ByteArrayInputStream(Base64.getMimeDecoder().decode(content));
+            return new ByteArrayInputStream(XMLUtils.decode(content));
         } catch (CertificateException e) {
             throw new MarshalException("Cannot create CertificateFactory", e);
         }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,20 +29,22 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
 
 import java.math.BigInteger;
 
 import javax.security.auth.x500.X500Principal;
-
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * DOM-based implementation of X509IssuerSerial.
  *
  */
-public final class DOMX509IssuerSerial extends BaseStructure
+public final class DOMX509IssuerSerial extends DOMStructure
     implements X509IssuerSerial {
 
     private final String issuerName;
@@ -89,17 +91,34 @@
         serialNumber = new BigInteger(sNElem.getFirstChild().getNodeValue());
     }
 
-    @Override
     public String getIssuerName() {
         return issuerName;
     }
 
-    @Override
     public BigInteger getSerialNumber() {
         return serialNumber;
     }
 
     @Override
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
+        throws MarshalException
+    {
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+
+        Element isElem = DOMUtils.createElement(ownerDoc, "X509IssuerSerial",
+                                                XMLSignature.XMLNS, dsPrefix);
+        Element inElem = DOMUtils.createElement(ownerDoc, "X509IssuerName",
+                                                XMLSignature.XMLNS, dsPrefix);
+        Element snElem = DOMUtils.createElement(ownerDoc, "X509SerialNumber",
+                                                XMLSignature.XMLNS, dsPrefix);
+        inElem.appendChild(ownerDoc.createTextNode(issuerName));
+        snElem.appendChild(ownerDoc.createTextNode(serialNumber.toString()));
+        isElem.appendChild(inElem);
+        isElem.appendChild(snElem);
+        parent.appendChild(isElem);
+    }
+
+    @Override
     public boolean equals(Object obj) {
         if (this == obj) {
             return true;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java	Tue Mar 05 08:24:58 2019 -0500
@@ -29,12 +29,14 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.*;
 
 import java.security.Provider;
 import java.util.*;
 
 import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
@@ -43,12 +45,13 @@
  * DOM-based implementation of XMLObject.
  *
  */
-public final class DOMXMLObject extends BaseStructure implements XMLObject {
+public final class DOMXMLObject extends DOMStructure implements XMLObject {
 
     private final String id;
     private final String mimeType;
     private final String encoding;
     private final List<XMLStructure> content;
+    private Element objectElem;
 
     /**
      * Creates an {@code XMLObject} from the specified parameters.
@@ -142,51 +145,56 @@
         } else {
             this.content = Collections.unmodifiableList(newContent);
         }
+        this.objectElem = objElem;
     }
 
-    @Override
     public List<XMLStructure> getContent() {
         return content;
     }
 
-    @Override
     public String getId() {
         return id;
     }
 
-    @Override
     public String getMimeType() {
         return mimeType;
     }
 
-    @Override
     public String getEncoding() {
         return encoding;
     }
 
-    public static void marshal(XmlWriter xwriter, XMLObject xmlObj, String dsPrefix, XMLCryptoContext context)
+    @Override
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException {
-        xwriter.writeStartElement(dsPrefix, "Object", XMLSignature.XMLNS);
+        Document ownerDoc = DOMUtils.getOwnerDocument(parent);
+
+        Element objElem = objectElem != null ? objectElem : null;
+        if (objElem == null) {
+            objElem = DOMUtils.createElement(ownerDoc, "Object",
+                                             XMLSignature.XMLNS, dsPrefix);
 
-        // set attributes
-        xwriter.writeIdAttribute("", "", "Id", xmlObj.getId());
-        xwriter.writeAttribute("", "", "MimeType", xmlObj.getMimeType());
-        xwriter.writeAttribute("", "", "Encoding", xmlObj.getEncoding());
+            // set attributes
+            DOMUtils.setAttributeID(objElem, "Id", id);
+            DOMUtils.setAttribute(objElem, "MimeType", mimeType);
+            DOMUtils.setAttribute(objElem, "Encoding", encoding);
 
-        // create and append any elements and mixed content, if necessary
-        @SuppressWarnings("unchecked")
-        List<XMLStructure> content = xmlObj.getContent();
-        for (XMLStructure object : content) {
-            xwriter.marshalStructure(object, dsPrefix, context);
+            // create and append any elements and mixed content, if necessary
+            for (XMLStructure object : content) {
+                if (object instanceof DOMStructure) {
+                    ((DOMStructure)object).marshal(objElem, dsPrefix, context);
+                } else {
+                    javax.xml.crypto.dom.DOMStructure domObject =
+                        (javax.xml.crypto.dom.DOMStructure)object;
+                    DOMUtils.appendChild(objElem, domObject.getNode());
+                }
+            }
         }
-        xwriter.writeEndElement(); // "Object"
+
+        parent.appendChild(objElem);
     }
 
     @SuppressWarnings("unchecked")
-    public static List<XMLStructure> getXmlObjectContent(XMLObject xo) {
-        return xo.getContent();
-    }
-
     @Override
     public boolean equals(Object o) {
         if (this == o) {
@@ -208,7 +216,7 @@
                               : mimeType.equals(oxo.getMimeType());
 
         return idsEqual && encodingsEqual && mimeTypesEqual &&
-                equalsContent(getXmlObjectContent(oxo));
+                equalsContent(oxo.getContent());
     }
 
     @Override
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java	Tue Mar 05 08:24:58 2019 -0500
@@ -36,6 +36,7 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.*;
+import javax.xml.crypto.dom.*;
 import javax.xml.crypto.dsig.*;
 import javax.xml.crypto.dsig.dom.DOMSignContext;
 import javax.xml.crypto.dsig.dom.DOMValidateContext;
@@ -46,11 +47,12 @@
 import java.security.Provider;
 import java.util.Collections;
 import java.util.ArrayList;
-import java.util.Base64;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -70,6 +72,9 @@
     private KeyInfo ki;
     private List<XMLObject> objects;
     private SignedInfo si;
+    private Document ownerDoc = null;
+    private Element localSigElem = null;
+    private Element sigElem = null;
     private boolean validationStatus;
     private boolean validated = false;
     private KeySelectorResult ksr;
@@ -127,7 +132,8 @@
                            Provider provider)
         throws MarshalException
     {
-        Element localSigElem = sigElem;
+        localSigElem = sigElem;
+        ownerDoc = localSigElem.getOwnerDocument();
 
         // get Id attribute, if specified
         id = DOMUtils.getAttributeValue(localSigElem, "Id");
@@ -171,69 +177,74 @@
         }
     }
 
-    @Override
     public String getId() {
         return id;
     }
 
-    @Override
     public KeyInfo getKeyInfo() {
         return ki;
     }
 
-    @Override
     public SignedInfo getSignedInfo() {
         return si;
     }
 
-    @Override
     public List<XMLObject> getObjects() {
         return objects;
     }
 
-    @Override
     public SignatureValue getSignatureValue() {
         return sv;
     }
 
-    @Override
     public KeySelectorResult getKeySelectorResult() {
         return ksr;
     }
 
     @Override
-    public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
+    public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
+        throws MarshalException
+    {
+        marshal(parent, null, dsPrefix, context);
+    }
+
+    public void marshal(Node parent, Node nextSibling, String dsPrefix,
+                        DOMCryptoContext context)
         throws MarshalException
     {
-        // rationalize the prefix.
-        String prefix = dsPrefix;
-        if (prefix == null) {
-            prefix = "";
+        ownerDoc = DOMUtils.getOwnerDocument(parent);
+        sigElem = DOMUtils.createElement(ownerDoc, "Signature",
+                                         XMLSignature.XMLNS, dsPrefix);
+
+        // append xmlns attribute
+        if (dsPrefix == null || dsPrefix.length() == 0) {
+            sigElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
+                                   XMLSignature.XMLNS);
+        } else {
+            sigElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" +
+                                   dsPrefix, XMLSignature.XMLNS);
         }
-        xwriter.writeStartElement(prefix, "Signature", XMLSignature.XMLNS);
-
-        xwriter.writeNamespace(prefix, XMLSignature.XMLNS);
-
-        // append Id attribute
-        xwriter.writeIdAttribute("", "", "Id", id);
 
         // create and append SignedInfo element
-        ((DOMSignedInfo) si).marshal(xwriter, prefix, context);
+        ((DOMSignedInfo)si).marshal(sigElem, dsPrefix, context);
 
         // create and append SignatureValue element
-        ((DOMSignatureValue) sv).marshal(xwriter, prefix, context);
+        ((DOMSignatureValue)sv).marshal(sigElem, dsPrefix, context);
 
         // create and append KeyInfo element if necessary
         if (ki != null) {
-            DOMKeyInfo.marshal(xwriter, ki, prefix, context);
+            ((DOMKeyInfo)ki).marshal(sigElem, null, dsPrefix, context);
         }
 
         // create and append Object elements if necessary
-        for (XMLObject xmlObj : objects) {
-            DOMXMLObject.marshal(xwriter, xmlObj, prefix, context);
+        for (int i = 0, size = objects.size(); i < size; i++) {
+            ((DOMXMLObject)objects.get(i)).marshal(sigElem, dsPrefix, context);
         }
 
-        xwriter.writeEndElement(); // "Signature"
+        // append Id attribute
+        DOMUtils.setAttributeID(sigElem, "Id", id);
+
+        parent.insertBefore(sigElem, nextSibling);
     }
 
     @Override
@@ -262,7 +273,8 @@
         }
 
         // validate all References
-        List<Reference> refs = DOMSignedInfo.getSignedInfoReferences(this.si);
+        @SuppressWarnings("unchecked")
+        List<Reference> refs = this.si.getReferences();
         boolean validateRefs = true;
         for (int i = 0, size = refs.size(); validateRefs && i < size; i++) {
             Reference ref = refs.get(i);
@@ -284,14 +296,16 @@
         {
             for (int i=0, size=objects.size(); validateMans && i < size; i++) {
                 XMLObject xo = objects.get(i);
-                List<XMLStructure> content = DOMXMLObject.getXmlObjectContent(xo);
+                @SuppressWarnings("unchecked")
+                List<XMLStructure> content = xo.getContent();
                 int csize = content.size();
                 for (int j = 0; validateMans && j < csize; j++) {
                     XMLStructure xs = content.get(j);
                     if (xs instanceof Manifest) {
                         LOG.debug("validating manifest");
                         Manifest man = (Manifest)xs;
-                        List<Reference> manRefs = DOMManifest.getManifestReferences(man);
+                        @SuppressWarnings("unchecked")
+                        List<Reference> manRefs = man.getReferences();
                         int rsize = manRefs.size();
                         for (int k = 0; validateMans && k < rsize; k++) {
                             Reference ref = manRefs.get(k);
@@ -319,13 +333,8 @@
             throw new NullPointerException("signContext cannot be null");
         }
         DOMSignContext context = (DOMSignContext)signContext;
-        Node nextSibling = context.getNextSibling();
-
-        XmlWriterToTree xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), context.getParent(), nextSibling);
-        marshal(xwriter,
-            DOMUtils.getSignaturePrefix(signContext), signContext);
-
-        Element sigElem = xwriter.getCreatedElement();
+        marshal(context.getParent(), context.getNextSibling(),
+                DOMUtils.getSignaturePrefix(context), context);
 
         // generate references and signature value
         List<Reference> allReferences = new ArrayList<>();
@@ -335,18 +344,21 @@
         signatureIdMap = new HashMap<>();
         signatureIdMap.put(id, this);
         signatureIdMap.put(si.getId(), si);
-        List<Reference> refs = DOMSignedInfo.getSignedInfoReferences(si);
+        @SuppressWarnings("unchecked")
+        List<Reference> refs = si.getReferences();
         for (Reference ref : refs) {
             signatureIdMap.put(ref.getId(), ref);
         }
         for (XMLObject obj : objects) {
             signatureIdMap.put(obj.getId(), obj);
-            List<XMLStructure> content = DOMXMLObject.getXmlObjectContent(obj);
+            @SuppressWarnings("unchecked")
+            List<XMLStructure> content = obj.getContent();
             for (XMLStructure xs : content) {
                 if (xs instanceof Manifest) {
                     Manifest man = (Manifest)xs;
                     signatureIdMap.put(man.getId(), man);
-                    List<Reference> manRefs = DOMManifest.getManifestReferences(man);
+                    @SuppressWarnings("unchecked")
+                    List<Reference> manRefs = man.getReferences();
                     for (Reference ref : manRefs) {
                         allReferences.add(ref);
                         signatureIdMap.put(ref.getId(), ref);
@@ -389,14 +401,14 @@
 
         // calculate signature value
         try {
-            Element sigValue = (Element) sigElem.getElementsByTagNameNS(XMLSignature.XMLNS, "SignatureValue").item(0);
-            xwriter.resetToNewParent(sigValue);
             byte[] val = ((AbstractDOMSignatureMethod)
-                si.getSignatureMethod()).sign(signingKey, (DOMSignedInfo) si, signContext);
-            ((DOMSignatureValue)sv).setValue(xwriter, val);
+                si.getSignatureMethod()).sign(signingKey, si, signContext);
+            ((DOMSignatureValue)sv).setValue(val);
         } catch (InvalidKeyException ike) {
             throw new XMLSignatureException(ike);
         }
+
+        this.localSigElem = sigElem;
     }
 
     @Override
@@ -484,6 +496,7 @@
         private String id;
         private byte[] value;
         private String valueBase64;
+        private Element sigValueElem;
         private boolean validated = false;
         private boolean validationStatus;
 
@@ -496,17 +509,22 @@
         {
             // base64 decode signatureValue
             String content = XMLUtils.getFullTextChildrenFromElement(sigValueElem);
-            value = Base64.getMimeDecoder().decode(content);
+            value = XMLUtils.decode(content);
 
-            id = DOMUtils.getIdAttributeValue(sigValueElem, "Id");
+            Attr attr = sigValueElem.getAttributeNodeNS(null, "Id");
+            if (attr != null) {
+                id = attr.getValue();
+                sigValueElem.setIdAttributeNode(attr, true);
+            } else {
+                id = null;
+            }
+            this.sigValueElem = sigValueElem;
         }
 
-        @Override
         public String getId() {
             return id;
         }
 
-        @Override
         public byte[] getValue() {
             return (value == null) ? null : value.clone();
         }
@@ -552,7 +570,7 @@
             // canonicalize SignedInfo and verify signature
             try {
                 validationStatus = ((AbstractDOMSignatureMethod)sm).verify
-                    (validationKey, (DOMSignedInfo) si, value, validateContext);
+                    (validationKey, si, value, validateContext);
             } catch (Exception e) {
                 throw new XMLSignatureException(e);
             }
@@ -590,29 +608,25 @@
             return result;
         }
 
-        @Override
-        public void marshal(XmlWriter xwriter, String dsPrefix,
-                XMLCryptoContext context)
+        public void marshal(Node parent, String dsPrefix,
+                            DOMCryptoContext context)
             throws MarshalException
         {
-            // create SignatureValue element
-            xwriter.writeStartElement(dsPrefix, "SignatureValue", XMLSignature.XMLNS);
+            sigValueElem = DOMUtils.createElement(ownerDoc, "SignatureValue",
+                                                  XMLSignature.XMLNS, dsPrefix);
+            if (valueBase64 != null) {
+                sigValueElem.appendChild(ownerDoc.createTextNode(valueBase64));
+            }
 
             // append Id attribute, if specified
-            xwriter.writeIdAttribute("", "", "Id", id);
-            if (valueBase64 != null) {
-                xwriter.writeCharacters(valueBase64);
-            }
-
-            xwriter.writeEndElement(); // "SignatureValue"
+            DOMUtils.setAttributeID(sigValueElem, "Id", id);
+            parent.appendChild(sigValueElem);
         }
 
-        void setValue(XmlWriter xwriter, byte[] value) {
+        void setValue(byte[] value) {
             this.value = value;
-            valueBase64 = Base64.getMimeEncoder().encodeToString(value);
-            if (xwriter != null) {
-                xwriter.writeCharacters(valueBase64);
-            }
+            valueBase64 = XMLUtils.encodeToString(value);
+            sigValueElem.appendChild(ownerDoc.createTextNode(valueBase64));
         }
     }
 }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java	Tue Mar 05 08:24:58 2019 -0500
@@ -54,24 +54,20 @@
      */
     public DOMXMLSignatureFactory() {}
 
-    @Override
     public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki) {
         return new DOMXMLSignature(si, ki, null, null, null);
     }
 
-    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki,
         List objects, String id, String signatureValueId) {
         return new DOMXMLSignature(si, ki, objects, id, signatureValueId);
     }
 
-    @Override
     public Reference newReference(String uri, DigestMethod dm) {
         return newReference(uri, dm, null, null, null);
     }
 
-    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public Reference newReference(String uri, DigestMethod dm, List transforms,
         String type, String id) {
@@ -96,7 +92,6 @@
             (uri, type, dm, appliedTransforms, result, transforms, id, getProvider());
     }
 
-    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public Reference newReference(String uri, DigestMethod dm, List transforms,
         String type, String id, byte[] digestValue) {
@@ -107,14 +102,12 @@
             (uri, type, dm, null, null, transforms, id, digestValue, getProvider());
     }
 
-    @Override
     @SuppressWarnings({ "rawtypes" })
     public SignedInfo newSignedInfo(CanonicalizationMethod cm,
         SignatureMethod sm, List references) {
         return newSignedInfo(cm, sm, references, null);
     }
 
-    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public SignedInfo newSignedInfo(CanonicalizationMethod cm,
         SignatureMethod sm, List references, String id) {
@@ -122,39 +115,33 @@
     }
 
     // Object factory methods
-    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public XMLObject newXMLObject(List content, String id, String mimeType,
         String encoding) {
         return new DOMXMLObject(content, id, mimeType, encoding);
     }
 
-    @Override
     @SuppressWarnings({ "rawtypes" })
     public Manifest newManifest(List references) {
         return newManifest(references, null);
     }
 
-    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public Manifest newManifest(List references, String id) {
         return new DOMManifest(references, id);
     }
 
-    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public SignatureProperties newSignatureProperties(List props, String id) {
         return new DOMSignatureProperties(props, id);
     }
 
-    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public SignatureProperty newSignatureProperty
         (List info, String target, String id) {
         return new DOMSignatureProperty(info, target, id);
     }
 
-    @Override
     public XMLSignature unmarshalXMLSignature(XMLValidateContext context)
         throws MarshalException {
 
@@ -164,7 +151,6 @@
         return unmarshal(((DOMValidateContext) context).getNode(), context);
     }
 
-    @Override
     public XMLSignature unmarshalXMLSignature(XMLStructure xmlStructure)
         throws MarshalException {
 
@@ -212,7 +198,6 @@
         }
     }
 
-    @Override
     public boolean isFeatureSupported(String feature) {
         if (feature == null) {
             throw new NullPointerException();
@@ -221,7 +206,6 @@
         }
     }
 
-    @Override
     public DigestMethod newDigestMethod(String algorithm,
         DigestMethodParameterSpec params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -255,7 +239,6 @@
         }
     }
 
-    @Override
     public SignatureMethod newSignatureMethod(String algorithm,
         SignatureMethodParameterSpec params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -321,7 +304,6 @@
         }
     }
 
-    @Override
     public Transform newTransform(String algorithm,
         TransformParameterSpec params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -341,7 +323,6 @@
         return new DOMTransform(spi);
     }
 
-    @Override
     public Transform newTransform(String algorithm,
         XMLStructure params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -364,7 +345,6 @@
         return new DOMTransform(spi);
     }
 
-    @Override
     public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
         C14NMethodParameterSpec params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -383,7 +363,6 @@
         return new DOMCanonicalizationMethod(spi);
     }
 
-    @Override
     public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
         XMLStructure params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -406,7 +385,6 @@
         return new DOMCanonicalizationMethod(spi);
     }
 
-    @Override
     public URIDereferencer getURIDereferencer() {
         return DOMURIDereferencer.INSTANCE;
     }
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java	Tue Mar 05 08:24:58 2019 -0500
@@ -57,7 +57,6 @@
  */
 public final class DOMXPathFilter2Transform extends ApacheTransform {
 
-    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException
     {
@@ -70,7 +69,6 @@
         this.params = params;
     }
 
-    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -126,7 +124,6 @@
         this.params = new XPathFilter2ParameterSpec(list);
     }
 
-    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java	Tue Mar 05 08:24:58 2019 -0500
@@ -60,7 +60,6 @@
         this.params = params;
     }
 
-    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -89,7 +88,6 @@
         }
     }
 
-    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java	Tue Mar 05 08:24:58 2019 -0500
@@ -55,7 +55,6 @@
         this.params = params;
     }
 
-    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException {
 
@@ -68,7 +67,6 @@
             (new javax.xml.crypto.dom.DOMStructure(sheet));
     }
 
-    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException {
         super.marshalParams(parent, context);
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Marshaller.java	Tue Mar 05 13:41:36 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,353 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.jcp.xml.dsig.internal.dom;
-
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.List;
-
-import javax.xml.XMLConstants;
-import javax.xml.crypto.MarshalException;
-import javax.xml.crypto.XMLCryptoContext;
-import javax.xml.crypto.XMLStructure;
-import javax.xml.crypto.dsig.DigestMethod;
-import javax.xml.crypto.dsig.Manifest;
-import javax.xml.crypto.dsig.SignatureProperties;
-import javax.xml.crypto.dsig.SignatureProperty;
-import javax.xml.crypto.dsig.XMLSignature;
-import javax.xml.crypto.dsig.keyinfo.KeyInfo;
-import javax.xml.crypto.dsig.keyinfo.KeyName;
-import javax.xml.crypto.dsig.keyinfo.KeyValue;
-import javax.xml.crypto.dsig.keyinfo.PGPData;
-import javax.xml.crypto.dsig.keyinfo.X509Data;
-import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-/**
- * Defines the individual marshallers for each of the different javax.xml.crypto structures.
- */
-class Marshaller {
-
-    private Marshaller() {
-        // complete
-    }
-
-    public static List<XmlWriter.ToMarshal<? extends XMLStructure>> getMarshallers() {
-        return MARSHALLERS;
-    }
-
-    /**
-     * Marshals a {@link KeyName}.
-     *
-     * @param xwriter
-     * @param keyName
-     * @param dsPrefix
-     */
-    public static void marshalKeyName(XmlWriter xwriter, KeyName keyName, String dsPrefix) {
-        xwriter.writeTextElement(dsPrefix, "KeyName", XMLSignature.XMLNS, keyName.getName());
-    }
-
-    /**
-     * Marshals a {@link PGPData}
-     *
-     * @param xwriter
-     * @param pgpData
-     * @param dsPrefix
-     * @param context
-     * @throws MarshalException
-     */
-    public static void marshalPGPData(XmlWriter xwriter, PGPData pgpData, String dsPrefix, XMLCryptoContext context)
-    throws MarshalException {
-        xwriter.writeStartElement(dsPrefix, "PGPData", XMLSignature.XMLNS);
-
-        // create and append PGPKeyID element
-        byte[] keyId = pgpData.getKeyId();
-        if (keyId != null) {
-            xwriter.writeTextElement(dsPrefix, "PGPKeyID", XMLSignature.XMLNS,
-                                     Base64.getMimeEncoder().encodeToString(keyId));
-        }
-
-        // create and append PGPKeyPacket element
-        byte[] keyPacket = pgpData.getKeyPacket();
-        if (keyPacket != null) {
-            xwriter.writeTextElement(dsPrefix, "XMLSignature.XMLNS", XMLSignature.XMLNS,
-                                     Base64.getMimeEncoder().encodeToString(keyPacket));
-        }
-
-        // create and append any elements
-        @SuppressWarnings("unchecked")
-        List<XMLStructure> externalElements = pgpData.getExternalElements();
-        for (XMLStructure externalItem : externalElements) {
-            xwriter.marshalStructure(externalItem, dsPrefix, context);
-        }
-
-        xwriter.writeEndElement(); // "PGPData"
-    }
-
-    /**
-     * Marshals an {@link X509IssuerSerial}
-     *
-     * @param xwriter
-     * @param issuerSerial
-     * @param dsPrefix
-     */
-    public static void marshalX509IssuerSerial(XmlWriter xwriter, X509IssuerSerial issuerSerial, String dsPrefix) {
-        xwriter.writeStartElement(dsPrefix, "X509IssuerSerial", XMLSignature.XMLNS);
-        xwriter.writeTextElement(dsPrefix, "X509IssuerName", XMLSignature.XMLNS,
-                issuerSerial.getIssuerName());
-
-        xwriter.writeTextElement(dsPrefix, "X509SerialNumber", XMLSignature.XMLNS,
-                issuerSerial.getSerialNumber().toString());
-
-        xwriter.writeEndElement(); // "X509IssuerSerial"
-    }
-
-    private static XmlWriter.ToMarshal<KeyName> Marshal_KeyName = new XmlWriter.ToMarshal<KeyName>(KeyName.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, KeyName toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            Marshaller.marshalKeyName(xwriter, toMarshal, dsPrefix);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<KeyInfo> Marshal_KeyInfo = new XmlWriter.ToMarshal<KeyInfo>(KeyInfo.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, KeyInfo toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            DOMKeyInfo.marshal(xwriter, toMarshal, dsPrefix, context);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<KeyValue> Marshal_KeyValue = new XmlWriter.ToMarshal<KeyValue>(KeyValue.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, KeyValue toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            // Since DOMKeyValue allows for deserializing unrecognized keys, and that
-            // capability isn't available via the KeyValue interface, this must continue
-            // to cast to DOMKeyValue.
-            DOMKeyValue<?> dkv = (DOMKeyValue<?>) toMarshal;
-            dkv.marshal( xwriter, dsPrefix, context);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<X509IssuerSerial> Marshal_X509IssuerSerial =
-            new XmlWriter.ToMarshal<X509IssuerSerial>(X509IssuerSerial.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, X509IssuerSerial toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            Marshaller.marshalX509IssuerSerial( xwriter, toMarshal, dsPrefix);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<X509Data> Marshal_X509Data =
-            new XmlWriter.ToMarshal<X509Data>(X509Data.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, X509Data toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            DOMX509Data.marshal( xwriter, toMarshal, dsPrefix, context);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<DigestMethod> Marshal_DigestMethod =
-            new XmlWriter.ToMarshal<DigestMethod>(DigestMethod.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, DigestMethod toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            DOMDigestMethod.marshal( xwriter, toMarshal, dsPrefix);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<PGPData> Marshal_PGPData =
-            new XmlWriter.ToMarshal<PGPData>(PGPData.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, PGPData toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            Marshaller.marshalPGPData( xwriter, toMarshal, dsPrefix, context);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<SignatureProperty> Marshal_SignatureProperty =
-            new XmlWriter.ToMarshal<SignatureProperty>(SignatureProperty.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, SignatureProperty toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            DOMSignatureProperty.marshal(xwriter, toMarshal, dsPrefix, context);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<SignatureProperties> Marshal_SignatureProperties =
-            new XmlWriter.ToMarshal<SignatureProperties>(SignatureProperties.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, SignatureProperties toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            DOMSignatureProperties.marshal(xwriter, toMarshal, dsPrefix, context);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<DOMSignatureMethod> Marshal_DOMSignatureMethod =
-            new XmlWriter.ToMarshal<DOMSignatureMethod>(DOMSignatureMethod.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, DOMSignatureMethod toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            toMarshal.marshal(xwriter, dsPrefix);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<DOMTransform> Marshal_DOMTransform =
-            new XmlWriter.ToMarshal<DOMTransform>(DOMTransform.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, DOMTransform toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            toMarshal.marshal(xwriter, dsPrefix, context);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<Manifest> Marshal_Manifest =
-            new XmlWriter.ToMarshal<Manifest>(Manifest.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, Manifest toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            DOMManifest.marshal(xwriter, toMarshal, dsPrefix, context);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<DOMStructure> Marshal_DOMStructure =
-            new XmlWriter.ToMarshal<DOMStructure>(DOMStructure.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, DOMStructure toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            toMarshal.marshal(xwriter, dsPrefix, context);
-        }
-    };
-
-    private static XmlWriter.ToMarshal<javax.xml.crypto.dom.DOMStructure> Marshal_JavaXDOMStructure =
-            new XmlWriter.ToMarshal<javax.xml.crypto.dom.DOMStructure>(javax.xml.crypto.dom.DOMStructure.class) {
-        @Override
-        public void marshalObject(XmlWriter xwriter, javax.xml.crypto.dom.DOMStructure toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException {
-            marshalGenericNode(xwriter, toMarshal);
-        }
-    };
-
-    private static final List<XmlWriter.ToMarshal<? extends XMLStructure>> MARSHALLERS =
-        new ArrayList<XmlWriter.ToMarshal<? extends XMLStructure>>();
-
-    static {
-        MARSHALLERS.add(Marshal_KeyName);
-        MARSHALLERS.add(Marshal_KeyInfo);
-        MARSHALLERS.add(Marshal_KeyValue);
-        MARSHALLERS.add(Marshal_X509IssuerSerial);
-        MARSHALLERS.add(Marshal_X509Data);
-        MARSHALLERS.add(Marshal_DigestMethod);
-        MARSHALLERS.add(Marshal_PGPData);
-        MARSHALLERS.add(Marshal_SignatureProperty);
-        MARSHALLERS.add(Marshal_SignatureProperties);
-        MARSHALLERS.add(Marshal_DOMSignatureMethod);
-        MARSHALLERS.add(Marshal_DOMTransform);
-        MARSHALLERS.add(Marshal_Manifest);
-        MARSHALLERS.add(Marshal_DOMStructure);
-        MARSHALLERS.add(Marshal_JavaXDOMStructure);
-    }
-
-    private static void marshalGenericNode(XmlWriter xwriter, javax.xml.crypto.dom.DOMStructure xmlStruct) {
-        Node node = xmlStruct.getNode();
-
-        // if it is a namespace, make a copy.
-        if (DOMUtils.isNamespace(node)) {
-            xwriter.writeNamespace(node.getLocalName(), node.getTextContent());
-        }
-        else if (Node.ATTRIBUTE_NODE == node.getNodeType() ) {
-            sendAttributeToWriter(xwriter, (Attr) node);
-        }
-        else {
-            marshalGenericNode(xwriter, node);
-        }
-    }
-
-    private static void marshalGenericNode(XmlWriter xwriter, Node node) {
-
-        short nodeType = node.getNodeType();
-        if (DOMUtils.isNamespace(node)) {
-            xwriter.writeNamespace(node.getLocalName(), node.getTextContent());
-        }
-        else if (nodeType == Node.ATTRIBUTE_NODE) {
-            // if it is an attribute, make a copy.
-            sendAttributeToWriter(xwriter, (Attr) node);
-        }
-        else {
-            switch (nodeType) {
-            case Node.ELEMENT_NODE:
-                xwriter.writeStartElement(node.getPrefix(), node.getLocalName(), node.getNamespaceURI());
-
-                // emit all the namespaces and attributes.
-                NamedNodeMap nnm = node.getAttributes();
-                for (int idx = 0 ; idx < nnm.getLength() ; idx++) {
-                    Attr attr = (Attr) nnm.item(idx);
-                    // is this a namespace node?
-                    if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(node.getNamespaceURI())) {
-                        xwriter.writeNamespace(attr.getLocalName(), attr.getValue());
-                    }
-                    else {
-                        // nope - standard attribute.
-                        sendAttributeToWriter(xwriter, attr);
-                    }
-                }
-                // now loop through all the children.
-                for (Node child = node.getFirstChild() ; child != null ; child = child.getNextSibling()) {
-                    marshalGenericNode(xwriter, child);
-                }
-                xwriter.writeEndElement();
-                break;
-            case Node.COMMENT_NODE:
-                xwriter.writeComment(node.getTextContent());
-                break;
-            case Node.TEXT_NODE:
-                xwriter.writeCharacters(node.getTextContent());
-                break;
-            default:
-                // unhandled - don't care to deal with processing instructions.
-                break;
-            }
-        }
-    }
-
-    private static void sendAttributeToWriter(XmlWriter xwriter, Attr attr) {
-        if (attr.isId()) {
-            xwriter.writeIdAttribute(attr.getPrefix(), attr.getNamespaceURI(),
-                    attr.getLocalName(), attr.getTextContent());
-        }
-        else {
-            if (attr.getNamespaceURI() == null && attr.getLocalName() == null) {
-                // Level 1 DOM attribute
-                xwriter.writeAttribute(null, null, attr.getName(), attr.getTextContent());
-            } else {
-                xwriter.writeAttribute(attr.getPrefix(), attr.getNamespaceURI(), attr.getLocalName(),
-                                       attr.getTextContent());
-            }
-        }
-    }
-
-}
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XmlWriter.java	Tue Mar 05 13:41:36 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.jcp.xml.dsig.internal.dom;
-
-import javax.xml.crypto.MarshalException;
-import javax.xml.crypto.XMLCryptoContext;
-import javax.xml.crypto.XMLStructure;
-
-import org.w3c.dom.Attr;
-
-/**
- * This interface is used to construct XML via a sequence of API calls.
- *
- * <p>This is written to be similar to javax.xml.stream.XMLStreamWriter, but
- * has slightly different requirements. Specifically, we need to be able to create
- * an "ID" type attribute, and get the current node.
- * </p>
- */
-public interface XmlWriter {
-
-    /**
-     * Utility class that brings together the class, and the method for marshaling an
-     * instance of said class.
-     *
-     * @param <CLZ>
-     */
-    abstract static class ToMarshal<CLZ extends XMLStructure> { //NOPMD
-        public final Class<CLZ> clazzToMatch;
-
-        public ToMarshal(Class<CLZ> clazzToMatch) {
-            this.clazzToMatch = clazzToMatch;
-        }
-
-        public abstract void marshalObject(XmlWriter xwriter, CLZ toMarshal, String dsPrefix,
-                XMLCryptoContext context) throws MarshalException;
-    }
-
-    /**
-     *
-     * @param prefix    What prefix to use?
-     * @param localName What local name to use?
-     * @param namespaceURI  What namespace URI?
-     *
-     * See also {@link javax.xml.stream.XMLStreamWriter#writeStartElement(String, String, String)}
-     */
-    void writeStartElement(String prefix, String localName, String namespaceURI);
-
-    /**
-     * See also {@link javax.xml.stream.XMLStreamWriter#writeEndElement()}
-     */
-    void writeEndElement();
-
-    /**
-     * Convenience method that writes both a start and end tag, with text contents as
-     * provided.
-     *
-     * @param prefix
-     * @param localName
-     * @param namespaceURI
-     * @param value
-     */
-    void writeTextElement(String prefix, String localName, String namespaceURI, String value);
-
-    void writeNamespace(String prefix, String namespaceURI);
-
-    void writeCharacters(String text);
-
-    void writeComment(String text);
-
-    Attr writeAttribute(String prefix, String namespaceURI, String localName, String value);
-
-    void writeIdAttribute(String prefix, String namespaceURI, String localName, String value);
-
-    /**
-     * Get the local name of the current element.
-     * @return the local name of the current element.
-     */
-    String getCurrentLocalName();
-
-    XMLStructure getCurrentNodeAsStructure();
-
-    /**
-     * This method marshals a structure, and relies on implementation specific details for how
-     * an instance of a particular class maps to the method that actually does the marshaling.
-     *
-     * @param toMarshal The object to be marshaled.
-     * @param dsPrefix  The digital signature prefix.
-     * @param context   The context for marshaling.
-     * @throws MarshalException Thrown if something goes wrong during the marshaling.
-     */
-    void marshalStructure(XMLStructure toMarshal, String dsPrefix, XMLCryptoContext context) throws MarshalException;
-}
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XmlWriterToTree.java	Tue Mar 05 13:41:36 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.jcp.xml.dsig.internal.dom;
-
-import java.util.List;
-
-import javax.xml.XMLConstants;
-import javax.xml.crypto.MarshalException;
-import javax.xml.crypto.XMLCryptoContext;
-import javax.xml.crypto.XMLStructure;
-import javax.xml.crypto.dom.DOMStructure;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Comment;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-
-/**
- * Manifestation of XmlWriter interface designed to write to a tree.
- */
-public class XmlWriterToTree implements XmlWriter {
-
-    private Document factory;
-
-    private Element createdElement;
-
-    private Node nextSibling;
-
-    private Node currentNode;
-
-    private List<XmlWriter.ToMarshal<? extends XMLStructure>> m_marshallers;
-
-    public XmlWriterToTree(List<XmlWriter.ToMarshal<? extends XMLStructure>> marshallers, Node parent) {
-        m_marshallers = marshallers;
-        factory = parent instanceof Document ? (Document)parent : parent.getOwnerDocument();
-        currentNode = parent;
-    }
-
-    /**
-     * Reset to a new parent so that the writer can be re-used.
-     * @param newParent
-     */
-    public void resetToNewParent(Node newParent) {
-        currentNode = newParent;
-        createdElement = null;
-    }
-
-    /**
-     * Get the root element created with this writer.
-     * @return the root element created with this writer.
-     */
-    public Element getCreatedElement() {
-        return createdElement;
-    }
-
-    /**
-     * In cases where the serialization is supposed to precede a specific
-     * element, we add an extra parameter to capture that. Only affects the
-     * first element insertion (obviously?).
-     *
-     * @param marshallers
-     * @param parent
-     * @param nextSibling The first element created will be created *before* this element.
-     */
-    public XmlWriterToTree(List<XmlWriter.ToMarshal<? extends XMLStructure>> marshallers, Node parent, Node nextSibling) {
-        this(marshallers, parent);
-        this.nextSibling = nextSibling;
-    }
-
-    @Override
-    public void writeStartElement(String prefix, String localName, String namespaceURI) {
-        if ("".equals(namespaceURI)) {
-            // Map global namespace from StAX to DOM
-            namespaceURI = null;
-        }
-
-        Element newElem = factory.createElementNS(namespaceURI, DOMUtils.getQNameString(prefix, localName));
-        if (nextSibling != null) {
-            newElem = (Element)nextSibling.getParentNode().insertBefore(newElem, nextSibling);
-        }
-        else {
-            newElem = (Element)currentNode.appendChild(newElem);
-        }
-        nextSibling = null;
-        currentNode = newElem;
-
-        if (createdElement == null) {
-            createdElement = newElem;
-        }
-    }
-
-    @Override
-    public void writeEndElement() {
-        currentNode = currentNode.getParentNode();
-    }
-
-
-    @Override
-    public void writeTextElement(String prefix, String localName, String namespaceURI, String value) {
-        writeStartElement(prefix, localName, namespaceURI);
-        writeCharacters(value);
-        writeEndElement();
-    }
-
-    @Override
-    public void writeNamespace(String prefix, String namespaceURI) {
-        if ("".equals(prefix) || prefix == null) {
-            writeAttribute(null, XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", namespaceURI);
-        }
-        else {
-            writeAttribute("xmlns", XMLConstants.XMLNS_ATTRIBUTE_NS_URI, prefix, namespaceURI);
-        }
-    }
-
-    @Override
-    public void writeCharacters(String text) {
-        Text textNode = factory.createTextNode(text);
-        currentNode.appendChild(textNode);
-    }
-
-
-    @Override
-    public void writeComment(String text) {
-        Comment commentNode = factory.createComment(text);
-        currentNode.appendChild(commentNode);
-    }
-
-    @Override
-    public Attr writeAttribute(String prefix, String namespaceURI, String localName, String value) {
-
-        Attr result = null;
-        if (value != null) {
-            if ("".equals(namespaceURI)) {
-                // Map global namespace from StAX to DOM
-                namespaceURI = null;
-            }
-
-            result = factory.createAttributeNS(namespaceURI, DOMUtils.getQNameString(prefix, localName));
-            result.setTextContent(value);
-            if (! (currentNode instanceof Element)) {
-                throw new IllegalStateException(
-                        "Attempting to add an attribute to something other than an element node. Node is "
-                                + currentNode.toString());
-            }
-            ( (Element)currentNode).setAttributeNodeNS(result);
-        }
-        return result;
-    }
-
-    @Override
-    public void writeIdAttribute(String prefix, String namespaceURI, String localName, String value) {
-        if (value == null) {
-            return;
-        }
-        Attr newAttr = writeAttribute(prefix, namespaceURI, localName, value);
-        ( (Element)currentNode).setIdAttributeNode(newAttr, true);
-    }
-
-
-    @Override
-    public String getCurrentLocalName() {
-        return currentNode.getLocalName();
-    }
-
-    @Override
-    public XMLStructure getCurrentNodeAsStructure() {
-        return new DOMStructure(currentNode);
-    }
-
-    @Override
-    public void marshalStructure(XMLStructure toMarshal, String dsPrefix, XMLCryptoContext context) throws MarshalException {
-
-        // look for the first isInstance match, and marshal to that.
-        for (int idx = 0 ; idx < m_marshallers.size() ; idx++) {
-            @SuppressWarnings("unchecked")
-            XmlWriter.ToMarshal<XMLStructure> marshaller = (ToMarshal<XMLStructure>) m_marshallers.get(idx);
-            if (marshaller.clazzToMatch.isInstance(toMarshal)) {
-                marshaller.marshalObject(this, toMarshal, dsPrefix, context);
-                return;
-            }
-        }
-        throw new IllegalArgumentException("Unable to marshal unexpected object of class " + toMarshal.getClass().toString());
-    }
-
-
-}
--- a/test/jdk/javax/xml/crypto/dsig/GenerationTests.java	Tue Mar 05 13:41:36 2019 +0100
+++ b/test/jdk/javax/xml/crypto/dsig/GenerationTests.java	Tue Mar 05 08:24:58 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 /**
  * @test
  * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349 8046949
- *      8046724 8079693 8177334 8205507 8210736
+ *      8046724 8079693 8177334 8205507 8210736 8217878
  * @summary Basic unit tests for generating XML Signatures with JSR 105
  * @modules java.base/sun.security.util
  *          java.base/sun.security.x509
@@ -126,8 +126,12 @@
     private final static String CRL =
         DATA_DIR + System.getProperty("file.separator") + "certs" +
         System.getProperty("file.separator") + "crl";
+    // XML Document with a DOCTYPE declaration
     private final static String ENVELOPE =
         DATA_DIR + System.getProperty("file.separator") + "envelope.xml";
+    // XML Document without a DOCTYPE declaration
+    private final static String ENVELOPE2 =
+        DATA_DIR + System.getProperty("file.separator") + "envelope2.xml";
     private static URIDereferencer httpUd = null;
     private final static String STYLESHEET =
         "http://www.w3.org/TR/xml-stylesheet";
@@ -328,6 +332,10 @@
         test_create_signature_reference_dependency();
         test_create_signature_with_attr_in_no_namespace();
         test_create_signature_with_empty_id();
+        test_create_signature_enveloping_over_doc(ENVELOPE, true);
+        test_create_signature_enveloping_over_doc(ENVELOPE2, true);
+        test_create_signature_enveloping_over_doc(ENVELOPE, false);
+        test_create_signature_enveloping_dom_level1();
 
         // run tests for detached signatures with local http server
         try (Http server = Http.startServer()) {
@@ -1038,6 +1046,109 @@
                                                "signature", null);
         DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 512), doc);
         sig.sign(dsc);
+
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_over_doc(String filename,
+        boolean pass) throws Exception
+    {
+        System.out.println("* Generating signature-enveloping-over-doc.xml");
+
+        // create reference
+        Reference ref = fac.newReference("#object", sha256);
+
+        // create SignedInfo
+        SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha256,
+            Collections.singletonList(ref));
+
+        // create object
+        Document doc = null;
+        try (FileInputStream fis = new FileInputStream(filename)) {
+            doc = db.parse(fis);
+        }
+        DOMStructure ds = pass ? new DOMStructure(doc.getDocumentElement())
+                               : new DOMStructure(doc);
+        XMLObject obj = fac.newXMLObject(Collections.singletonList(ds),
+            "object", null, "UTF-8");
+
+        // This creates an enveloping signature over the entire XML Document
+        XMLSignature sig = fac.newXMLSignature(si, rsa,
+                                               Collections.singletonList(obj),
+                                               "signature", null);
+        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 1024), doc);
+        try {
+            sig.sign(dsc);
+            if (!pass) {
+                // A Document node can only exist at the root of the doc so this
+                // should fail
+                throw new Exception("Test unexpectedly passed");
+            }
+        } catch (Exception e) {
+            if (!pass) {
+                System.out.println("Test failed as expected: " + e);
+            } else {
+                throw e;
+            }
+        }
+
+        if (pass) {
+            DOMValidateContext dvc = new DOMValidateContext
+                (getPublicKey("RSA", 1024), doc.getDocumentElement());
+            XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
+
+            if (sig.equals(sig2) == false) {
+                throw new Exception
+                    ("Unmarshalled signature is not equal to generated signature");
+            }
+            if (sig2.validate(dvc) == false) {
+                throw new Exception("Validation of generated signature failed");
+            }
+        }
+
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_dom_level1() throws Exception {
+        System.out.println("* Generating signature-enveloping-dom-level1.xml");
+
+        // create reference
+        Reference ref = fac.newReference("#object", sha256);
+
+        // create SignedInfo
+        SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha256,
+            Collections.singletonList(ref));
+
+        // create object using DOM Level 1 methods
+        Document doc = db.newDocument();
+        Element child = doc.createElement("Child");
+        child.setAttribute("Version", "1.0");
+        child.setAttribute("Id", "child");
+        child.setIdAttribute("Id", true);
+        child.appendChild(doc.createComment("Comment"));
+        XMLObject obj = fac.newXMLObject(
+            Collections.singletonList(new DOMStructure(child)),
+            "object", null, "UTF-8");
+
+        XMLSignature sig = fac.newXMLSignature(si, rsa,
+                                               Collections.singletonList(obj),
+                                               "signature", null);
+        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 1024), doc);
+        sig.sign(dsc);
+
+        DOMValidateContext dvc = new DOMValidateContext
+            (getPublicKey("RSA", 1024), doc.getDocumentElement());
+        XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
+
+        if (sig.equals(sig2) == false) {
+            throw new Exception
+                ("Unmarshalled signature is not equal to generated signature");
+        }
+        if (sig2.validate(dvc) == false) {
+            throw new Exception("Validation of generated signature failed");
+        }
+
+        System.out.println();
     }
 
     static void test_create_signature() throws Exception {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/xml/crypto/dsig/data/envelope2.xml	Tue Mar 05 08:24:58 2019 -0500
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Preamble -->
+<Envelope xmlns:foo="http://example.org/foo" xmlns="http://example.org/usps">
+  <DearSir>foo</DearSir>
+  <Body>bar</Body>
+  <YoursSincerely>
+  </YoursSincerely>
+  <PostScript>bar</PostScript>
+  <Notaries xmlns="" Id="notaries">
+    <Notary name="Great, A. T." />
+    <Notary name="Hun, A. T." />
+  </Notaries>
+  <!-- Commentary -->
+</Envelope>
+<!-- Postamble -->