All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.xml.security.c14n.implementations.Canonicalizer20010315Excl Maven / Gradle / Ivy

/**
 * 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.apache.xml.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 org.apache.xml.security.c14n.CanonicalizationException;
import org.apache.xml.security.c14n.helper.C14nHelper;
import org.apache.xml.security.signature.XMLSignatureInput;
import org.apache.xml.security.transforms.params.InclusiveNamespaces;
import org.apache.xml.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;

/**
 * Implements " Exclusive XML
 * Canonicalization, Version 1.0 " 

* Credits: During restructuring of the Canonicalizer framework, Ren?? * Kollmorgen from Software AG submitted an implementation of ExclC14n which * fitted into the old architecture and which based heavily on my old (and slow) * implementation of "Canonical XML". A big "thank you" to Ren?? for this. *

* THIS implementation is a complete rewrite of the algorithm. * * @see * Exclusive XML Canonicalization, Version 1.0 */ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase { /** * This Set contains the names (Strings like "xmlns" or "xmlns:foo") of * the inclusive namespaces. */ private SortedSet inclusiveNSSet; private boolean propagateDefaultNamespace = false; /** * Constructor Canonicalizer20010315Excl * * @param includeComments */ public Canonicalizer20010315Excl(boolean includeComments) { super(includeComments); } /** * Method engineCanonicalizeSubTree * {@inheritDoc} * @param rootNode * * @throws CanonicalizationException */ public byte[] engineCanonicalizeSubTree(Node rootNode) throws CanonicalizationException { return engineCanonicalizeSubTree(rootNode, "", null); } /** * Method engineCanonicalizeSubTree * {@inheritDoc} * @param rootNode * @param inclusiveNamespaces * * @throws CanonicalizationException */ public byte[] engineCanonicalizeSubTree( Node rootNode, String inclusiveNamespaces ) throws CanonicalizationException { return engineCanonicalizeSubTree(rootNode, inclusiveNamespaces, null); } /** * Method engineCanonicalizeSubTree * {@inheritDoc} * @param rootNode * @param inclusiveNamespaces * @param propagateDefaultNamespace If true the default namespace will be propagated to the c14n-ized root element * * @throws CanonicalizationException */ public byte[] engineCanonicalizeSubTree( Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace ) throws CanonicalizationException { this.propagateDefaultNamespace = propagateDefaultNamespace; return engineCanonicalizeSubTree(rootNode, inclusiveNamespaces, null); } /** * Method engineCanonicalizeSubTree * @param rootNode * @param inclusiveNamespaces * @param excl A element to exclude from the c14n process. * @return the rootNode c14n. * @throws CanonicalizationException */ public byte[] engineCanonicalizeSubTree( Node rootNode, String inclusiveNamespaces, Node excl ) throws CanonicalizationException{ inclusiveNSSet = InclusiveNamespaces.prefixStr2Set(inclusiveNamespaces); return super.engineCanonicalizeSubTree(rootNode, excl); } /** * * @param rootNode * @param inclusiveNamespaces * @return the rootNode c14n. * @throws CanonicalizationException */ public byte[] engineCanonicalize( XMLSignatureInput rootNode, String inclusiveNamespaces ) throws CanonicalizationException { inclusiveNSSet = InclusiveNamespaces.prefixStr2Set(inclusiveNamespaces); return super.engineCanonicalize(rootNode); } /** * Method engineCanonicalizeXPathNodeSet * {@inheritDoc} * @param xpathNodeSet * @param inclusiveNamespaces * @throws CanonicalizationException */ public byte[] engineCanonicalizeXPathNodeSet( Set xpathNodeSet, String inclusiveNamespaces ) throws CanonicalizationException { inclusiveNSSet = InclusiveNamespaces.prefixStr2Set(inclusiveNamespaces); return super.engineCanonicalizeXPathNodeSet(xpathNodeSet); } @Override protected void outputAttributesSubtree(Element element, NameSpaceSymbTable ns, Map cache) throws CanonicalizationException, DOMException, IOException { // result will contain the attrs which have to be output SortedSet result = new TreeSet(COMPARE); // The prefix visibly utilized (in the attribute or in the name) in // the element SortedSet visiblyUtilized = new TreeSet(); 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 // visiblyUtilized String prefix = attribute.getPrefix(); if (prefix != null && !(prefix.equals(XML) || prefix.equals(XMLNS))) { visiblyUtilized.add(prefix); } // Add to the result. 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. // New definition check if it is relative. 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(); //we output all Attrs which are available for (Attr attr : result) { outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache); } } @Override protected void outputAttributes(Element element, NameSpaceSymbTable ns, Map cache) throws CanonicalizationException, DOMException, IOException { // result will contain the attrs which have to be output SortedSet result = new TreeSet(COMPARE); // The prefix visibly utilized (in the attribute or in the name) in // the element Set visiblyUtilized = null; // It's the output selected. boolean isOutputElement = isVisibleDO(element, ns.getLevel()) == 1; if (isOutputElement) { visiblyUtilized = new TreeSet(); 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) // to visibyUtilized String prefix = attribute.getPrefix(); if (prefix != null && !(prefix.equals(XML) || prefix.equals(XMLNS))) { visiblyUtilized.add(prefix); } // Add to the result. 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)) { // New definition check if it is relative Object exArgs[] = { element.getTagName(), NName, attribute.getNodeValue() }; throw new CanonicalizationException( "c14n.Canonicalizer.RelativeNamespace", exArgs ); } } } } if (isOutputElement) { // The element is visible, handle the xmlns definition Attr xmlns = element.getAttributeNodeNS(XMLNS_URI, XMLNS); if (xmlns != null && !isVisible(xmlns)) { // There is a definition but the xmlns is not selected by the // xpath. then xmlns="" 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(); //we output all Attrs which are available 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); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy