| 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
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.transforms.params.InclusiveNamespaces;  | 
 | 
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 Canonicalizer20010315Excl extends CanonicalizerBase { | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private SortedSet<String> inclusiveNSSet;  | 
 | 
    private boolean propagateDefaultNamespace = false;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public Canonicalizer20010315Excl(boolean includeComments) { | 
 | 
        super(includeComments);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public byte[] engineCanonicalizeSubTree(Node rootNode)  | 
 | 
        throws CanonicalizationException { | 
 | 
        return engineCanonicalizeSubTree(rootNode, "", null);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public byte[] engineCanonicalizeSubTree(  | 
 | 
        Node rootNode, String inclusiveNamespaces  | 
 | 
    ) throws CanonicalizationException { | 
 | 
        return engineCanonicalizeSubTree(rootNode, inclusiveNamespaces, null);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public byte[] engineCanonicalizeSubTree(  | 
 | 
            Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace  | 
 | 
    ) throws CanonicalizationException { | 
 | 
        this.propagateDefaultNamespace = propagateDefaultNamespace;  | 
 | 
        return engineCanonicalizeSubTree(rootNode, inclusiveNamespaces, null);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public byte[] engineCanonicalizeSubTree(  | 
 | 
        Node rootNode, String inclusiveNamespaces, Node excl  | 
 | 
    ) throws CanonicalizationException{ | 
 | 
        inclusiveNSSet = InclusiveNamespaces.prefixStr2Set(inclusiveNamespaces);  | 
 | 
        return super.engineCanonicalizeSubTree(rootNode, excl);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public byte[] engineCanonicalize(  | 
 | 
        XMLSignatureInput rootNode, String inclusiveNamespaces  | 
 | 
    ) throws CanonicalizationException { | 
 | 
        inclusiveNSSet = InclusiveNamespaces.prefixStr2Set(inclusiveNamespaces);  | 
 | 
        return super.engineCanonicalize(rootNode);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public byte[] engineCanonicalizeXPathNodeSet(  | 
 | 
        Set<Node> xpathNodeSet, String inclusiveNamespaces  | 
 | 
    ) throws CanonicalizationException { | 
 | 
        inclusiveNSSet = InclusiveNamespaces.prefixStr2Set(inclusiveNamespaces);  | 
 | 
        return super.engineCanonicalizeXPathNodeSet(xpathNodeSet);  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    protected void outputAttributesSubtree(Element element, NameSpaceSymbTable ns,  | 
 | 
                                           Map<String, byte[]> cache)  | 
 | 
        throws CanonicalizationException, DOMException, IOException { | 
 | 
          | 
 | 
        SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);  | 
 | 
 | 
 | 
        // The prefix visibly utilized (in the attribute or in the name) in  | 
 | 
          | 
 | 
        SortedSet<String> visiblyUtilized = new TreeSet<String>();  | 
 | 
        if (inclusiveNSSet != null && !inclusiveNSSet.isEmpty()) { | 
 | 
            visiblyUtilized.addAll(inclusiveNSSet);  | 
 | 
        }  | 
 | 
 | 
 | 
        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 NName = attribute.getLocalName();  | 
 | 
                String NNodeValue = attribute.getNodeValue();  | 
 | 
 | 
 | 
                if (!XMLNS_URI.equals(attribute.getNamespaceURI())) { | 
 | 
                    // Not a namespace definition.  | 
 | 
                    // The Element is output element, add the prefix (if used) to  | 
 | 
                      | 
 | 
                    String prefix = attribute.getPrefix();  | 
 | 
                    if (prefix != null && !(prefix.equals(XML) || prefix.equals(XMLNS))) { | 
 | 
                        visiblyUtilized.add(prefix);  | 
 | 
                    }  | 
 | 
                      | 
 | 
                    result.add(attribute);  | 
 | 
                } else if (!(XML.equals(NName) && XML_LANG_URI.equals(NNodeValue))  | 
 | 
                    && ns.addMapping(NName, NNodeValue, attribute)  | 
 | 
                    && C14nHelper.namespaceIsRelative(NNodeValue)) { | 
 | 
                    // The default mapping for xml must not be output.  | 
 | 
                      | 
 | 
                    Object exArgs[] = {element.getTagName(), NName, attribute.getNodeValue()}; | 
 | 
                    throw new CanonicalizationException(  | 
 | 
                        "c14n.Canonicalizer.RelativeNamespace", exArgs  | 
 | 
                    );  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
        if (propagateDefaultNamespace && ns.getLevel() == 1 &&  | 
 | 
                inclusiveNSSet.contains(XMLNS) &&  | 
 | 
                ns.getMappingWithoutRendered(XMLNS) == null) { | 
 | 
                ns.removeMapping(XMLNS);  | 
 | 
                ns.addMapping(  | 
 | 
                    XMLNS, "", getNullNode(element.getOwnerDocument()));  | 
 | 
        }  | 
 | 
        String prefix = null;  | 
 | 
        if (element.getNamespaceURI() != null  | 
 | 
            && !(element.getPrefix() == null || element.getPrefix().length() == 0)) { | 
 | 
            prefix = element.getPrefix();  | 
 | 
        } else { | 
 | 
            prefix = XMLNS;  | 
 | 
        }  | 
 | 
        visiblyUtilized.add(prefix);  | 
 | 
 | 
 | 
        for (String s : visiblyUtilized) { | 
 | 
            Attr key = ns.getMapping(s);  | 
 | 
            if (key != null) { | 
 | 
                result.add(key);  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        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 { | 
 | 
          | 
 | 
        SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);  | 
 | 
 | 
 | 
        // The prefix visibly utilized (in the attribute or in the name) in  | 
 | 
          | 
 | 
        Set<String> visiblyUtilized = null;  | 
 | 
          | 
 | 
        boolean isOutputElement = isVisibleDO(element, ns.getLevel()) == 1;  | 
 | 
        if (isOutputElement) { | 
 | 
            visiblyUtilized = new TreeSet<String>();  | 
 | 
            if (inclusiveNSSet != null && !inclusiveNSSet.isEmpty()) { | 
 | 
                visiblyUtilized.addAll(inclusiveNSSet);  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        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 NName = attribute.getLocalName();  | 
 | 
                String NNodeValue = attribute.getNodeValue();  | 
 | 
 | 
 | 
                if (!XMLNS_URI.equals(attribute.getNamespaceURI())) { | 
 | 
                    if (isVisible(attribute) && isOutputElement) { | 
 | 
                        // The Element is output element, add the prefix (if used)  | 
 | 
                          | 
 | 
                        String prefix = attribute.getPrefix();  | 
 | 
                        if (prefix != null && !(prefix.equals(XML) || prefix.equals(XMLNS))) { | 
 | 
                            visiblyUtilized.add(prefix);  | 
 | 
                        }  | 
 | 
                          | 
 | 
                        result.add(attribute);  | 
 | 
                    }  | 
 | 
                } else if (isOutputElement && !isVisible(attribute) && !XMLNS.equals(NName)) { | 
 | 
                    ns.removeMappingIfNotRender(NName);  | 
 | 
                } else { | 
 | 
                    if (!isOutputElement && isVisible(attribute)  | 
 | 
                        && inclusiveNSSet.contains(NName)  | 
 | 
                        && !ns.removeMappingIfRender(NName)) { | 
 | 
                        Node n = ns.addMappingAndRender(NName, NNodeValue, 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 (ns.addMapping(NName, NNodeValue, attribute)  | 
 | 
                        && C14nHelper.namespaceIsRelative(NNodeValue)) { | 
 | 
                          | 
 | 
                        Object exArgs[] = { element.getTagName(), NName, attribute.getNodeValue() }; | 
 | 
                        throw new CanonicalizationException(  | 
 | 
                            "c14n.Canonicalizer.RelativeNamespace", exArgs  | 
 | 
                        );  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        if (isOutputElement) { | 
 | 
              | 
 | 
            Attr xmlns = element.getAttributeNodeNS(XMLNS_URI, XMLNS);  | 
 | 
            if (xmlns != null && !isVisible(xmlns)) { | 
 | 
                // There is a definition but the xmlns is not selected by the  | 
 | 
                  | 
 | 
                ns.addMapping(XMLNS, "", getNullNode(xmlns.getOwnerDocument()));  | 
 | 
            }  | 
 | 
 | 
 | 
            String prefix = null;  | 
 | 
            if (element.getNamespaceURI() != null  | 
 | 
                && !(element.getPrefix() == null || element.getPrefix().length() == 0)) { | 
 | 
                prefix = element.getPrefix();  | 
 | 
            } else { | 
 | 
                prefix = XMLNS;  | 
 | 
            }  | 
 | 
            visiblyUtilized.add(prefix);  | 
 | 
 | 
 | 
            for (String s : visiblyUtilized) { | 
 | 
                Attr key = ns.getMapping(s);  | 
 | 
                if (key != null) { | 
 | 
                    result.add(key);  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        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() || inclusiveNSSet.isEmpty()) { | 
 | 
            return;  | 
 | 
        }  | 
 | 
        Document doc = null;  | 
 | 
        if (input.getSubNode() != null) { | 
 | 
            doc = XMLUtils.getOwnerDocument(input.getSubNode());  | 
 | 
        } else { | 
 | 
            doc = XMLUtils.getOwnerDocument(input.getNodeSet());  | 
 | 
        }  | 
 | 
        XMLUtils.circumventBug2650(doc);  | 
 | 
    }  | 
 | 
}  |