|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package com.sun.org.apache.xml.internal.security.c14n.implementations; |
|
|
|
import java.io.IOException; |
|
import java.io.OutputStream; |
|
import java.util.Map; |
|
import java.util.Set; |
|
import java.util.SortedSet; |
|
import java.util.TreeSet; |
|
|
|
import javax.xml.parsers.ParserConfigurationException; |
|
|
|
import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; |
|
import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper; |
|
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; |
|
import com.sun.org.apache.xml.internal.security.utils.XMLUtils; |
|
import org.w3c.dom.Attr; |
|
import org.w3c.dom.DOMException; |
|
import org.w3c.dom.Document; |
|
import org.w3c.dom.Element; |
|
import org.w3c.dom.NamedNodeMap; |
|
import org.w3c.dom.Node; |
|
import org.xml.sax.SAXException; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public abstract class Canonicalizer20010315 extends CanonicalizerBase { |
|
|
|
private boolean firstCall = true; |
|
|
|
private final XmlAttrStack xmlattrStack; |
|
private final boolean c14n11; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Canonicalizer20010315(boolean includeComments) { |
|
this(includeComments, false); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Canonicalizer20010315(boolean includeComments, boolean c14n11) { |
|
super(includeComments); |
|
xmlattrStack = new XmlAttrStack(c14n11); |
|
this.c14n11 = c14n11; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public byte[] engineCanonicalizeXPathNodeSet(Set<Node> xpathNodeSet, String inclusiveNamespaces) |
|
throws CanonicalizationException { |
|
|
|
|
|
throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation"); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public byte[] engineCanonicalizeSubTree(Node rootNode, String inclusiveNamespaces) |
|
throws CanonicalizationException { |
|
|
|
|
|
throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation"); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public byte[] engineCanonicalizeSubTree( |
|
Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace) |
|
throws CanonicalizationException { |
|
|
|
|
|
throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation"); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
@Override |
|
protected void outputAttributesSubtree(Element element, NameSpaceSymbTable ns, |
|
Map<String, byte[]> cache) |
|
throws CanonicalizationException, DOMException, IOException { |
|
if (!element.hasAttributes() && !firstCall) { |
|
return; |
|
} |
|
|
|
SortedSet<Attr> result = new TreeSet<Attr>(COMPARE); |
|
|
|
if (element.hasAttributes()) { |
|
NamedNodeMap attrs = element.getAttributes(); |
|
int attrsLength = attrs.getLength(); |
|
|
|
for (int i = 0; i < attrsLength; i++) { |
|
Attr attribute = (Attr) attrs.item(i); |
|
String NUri = attribute.getNamespaceURI(); |
|
String NName = attribute.getLocalName(); |
|
String NValue = attribute.getValue(); |
|
|
|
if (!XMLNS_URI.equals(NUri)) { |
|
|
|
result.add(attribute); |
|
} else if (!(XML.equals(NName) && XML_LANG_URI.equals(NValue))) { |
|
|
|
Node n = ns.addMappingAndRender(NName, NValue, attribute); |
|
|
|
if (n != null) { |
|
|
|
result.add((Attr)n); |
|
if (C14nHelper.namespaceIsRelative(attribute)) { |
|
Object exArgs[] = { element.getTagName(), NName, attribute.getNodeValue() }; |
|
throw new CanonicalizationException( |
|
"c14n.Canonicalizer.RelativeNamespace", exArgs |
|
); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (firstCall) { |
|
//It is the first node of the subtree |
|
|
|
ns.getUnrenderedNodes(result); |
|
|
|
xmlattrStack.getXmlnsAttr(result); |
|
firstCall = false; |
|
} |
|
|
|
OutputStream writer = getWriter(); |
|
|
|
for (Attr attr : result) { |
|
outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
@Override |
|
protected void outputAttributes(Element element, NameSpaceSymbTable ns, |
|
Map<String, byte[]> cache) |
|
throws CanonicalizationException, DOMException, IOException { |
|
|
|
xmlattrStack.push(ns.getLevel()); |
|
boolean isRealVisible = isVisibleDO(element, ns.getLevel()) == 1; |
|
SortedSet<Attr> result = new TreeSet<Attr>(COMPARE); |
|
|
|
if (element.hasAttributes()) { |
|
NamedNodeMap attrs = element.getAttributes(); |
|
int attrsLength = attrs.getLength(); |
|
|
|
for (int i = 0; i < attrsLength; i++) { |
|
Attr attribute = (Attr) attrs.item(i); |
|
String NUri = attribute.getNamespaceURI(); |
|
String NName = attribute.getLocalName(); |
|
String NValue = attribute.getValue(); |
|
|
|
if (!XMLNS_URI.equals(NUri)) { |
|
|
|
if (XML_LANG_URI.equals(NUri)) { |
|
if (c14n11 && "id".equals(NName)) { |
|
if (isRealVisible) { |
|
// treat xml:id like any other attribute |
|
|
|
result.add(attribute); |
|
} |
|
} else { |
|
xmlattrStack.addXmlnsAttr(attribute); |
|
} |
|
} else if (isRealVisible) { |
|
|
|
result.add(attribute); |
|
} |
|
} else if (!XML.equals(NName) || !XML_LANG_URI.equals(NValue)) { |
|
/* except omit namespace node with local name xml, which defines |
|
* the xml prefix, if its string value is http://www.w3.org/XML/1998/namespace. |
|
*/ |
|
|
|
if (isVisible(attribute)) { |
|
if (isRealVisible || !ns.removeMappingIfRender(NName)) { |
|
|
|
Node n = ns.addMappingAndRender(NName, NValue, attribute); |
|
if (n != null) { |
|
result.add((Attr)n); |
|
if (C14nHelper.namespaceIsRelative(attribute)) { |
|
Object exArgs[] = { element.getTagName(), NName, attribute.getNodeValue() }; |
|
throw new CanonicalizationException( |
|
"c14n.Canonicalizer.RelativeNamespace", exArgs |
|
); |
|
} |
|
} |
|
} |
|
} else { |
|
if (isRealVisible && !XMLNS.equals(NName)) { |
|
ns.removeMapping(NName); |
|
} else { |
|
ns.addMapping(NName, NValue, attribute); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if (isRealVisible) { |
|
|
|
Attr xmlns = element.getAttributeNodeNS(XMLNS_URI, XMLNS); |
|
Node n = null; |
|
if (xmlns == null) { |
|
|
|
n = ns.getMapping(XMLNS); |
|
} else if (!isVisible(xmlns)) { |
|
//There is a definition but the xmlns is not selected by the xpath. |
|
|
|
n = ns.addMappingAndRender( |
|
XMLNS, "", getNullNode(xmlns.getOwnerDocument())); |
|
} |
|
|
|
if (n != null) { |
|
result.add((Attr)n); |
|
} |
|
|
|
xmlattrStack.getXmlnsAttr(result); |
|
ns.getUnrenderedNodes(result); |
|
} |
|
|
|
OutputStream writer = getWriter(); |
|
|
|
for (Attr attr : result) { |
|
outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache); |
|
} |
|
} |
|
|
|
protected void circumventBugIfNeeded(XMLSignatureInput input) |
|
throws CanonicalizationException, ParserConfigurationException, IOException, SAXException { |
|
if (!input.isNeedsToBeExpanded()) { |
|
return; |
|
} |
|
Document doc = null; |
|
if (input.getSubNode() != null) { |
|
doc = XMLUtils.getOwnerDocument(input.getSubNode()); |
|
} else { |
|
doc = XMLUtils.getOwnerDocument(input.getNodeSet()); |
|
} |
|
XMLUtils.circumventBug2650(doc); |
|
} |
|
|
|
@Override |
|
protected void handleParent(Element e, NameSpaceSymbTable ns) { |
|
if (!e.hasAttributes() && e.getNamespaceURI() == null) { |
|
return; |
|
} |
|
xmlattrStack.push(-1); |
|
NamedNodeMap attrs = e.getAttributes(); |
|
int attrsLength = attrs.getLength(); |
|
for (int i = 0; i < attrsLength; i++) { |
|
Attr attribute = (Attr) attrs.item(i); |
|
String NName = attribute.getLocalName(); |
|
String NValue = attribute.getNodeValue(); |
|
|
|
if (XMLNS_URI.equals(attribute.getNamespaceURI())) { |
|
if (!XML.equals(NName) || !XML_LANG_URI.equals(NValue)) { |
|
ns.addMapping(NName, NValue, attribute); |
|
} |
|
} else if (XML_LANG_URI.equals(attribute.getNamespaceURI()) |
|
&& (!c14n11 || !"id".equals(NName))) { |
|
xmlattrStack.addXmlnsAttr(attribute); |
|
} |
|
} |
|
if (e.getNamespaceURI() != null) { |
|
String NName = e.getPrefix(); |
|
String NValue = e.getNamespaceURI(); |
|
String Name; |
|
if (NName == null || NName.equals("")) { |
|
NName = "xmlns"; |
|
Name = "xmlns"; |
|
} else { |
|
Name = "xmlns:" + NName; |
|
} |
|
Attr n = e.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/", Name); |
|
n.setValue(NValue); |
|
ns.addMapping(NName, NValue, n); |
|
} |
|
} |
|
} |