0N/A/*
0N/A * reserved comment block
0N/A * DO NOT REMOVE OR ALTER!
0N/A */
0N/A/*
0N/A * Copyright 1999-2004 The Apache Software Foundation.
0N/A *
0N/A * Licensed under the Apache License, Version 2.0 (the "License"); you may not
0N/A * use this file except in compliance with the License. You may obtain a copy of
0N/A * the License at
0N/A *
0N/A * http://www.apache.org/licenses/LICENSE-2.0
0N/A *
0N/A * Unless required by applicable law or agreed to in writing, software
0N/A * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
0N/A * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
0N/A * License for the specific language governing permissions and limitations under
0N/A * the License.
0N/A *
0N/A */
0N/Apackage com.sun.org.apache.xml.internal.security.c14n.implementations;
0N/A
661N/Aimport java.io.IOException;
0N/Aimport java.util.Iterator;
0N/Aimport java.util.Set;
0N/Aimport java.util.SortedSet;
0N/Aimport java.util.TreeSet;
0N/A
661N/Aimport javax.xml.parsers.ParserConfigurationException;
661N/A
0N/Aimport com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
0N/Aimport com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper;
0N/Aimport com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
0N/Aimport com.sun.org.apache.xml.internal.security.transforms.params.InclusiveNamespaces;
0N/Aimport com.sun.org.apache.xml.internal.security.utils.Constants;
661N/Aimport com.sun.org.apache.xml.internal.security.utils.XMLUtils;
0N/Aimport org.w3c.dom.Attr;
661N/Aimport org.w3c.dom.Document;
0N/Aimport org.w3c.dom.Element;
0N/Aimport org.w3c.dom.NamedNodeMap;
0N/Aimport org.w3c.dom.Node;
661N/Aimport org.xml.sax.SAXException;
0N/A/**
0N/A * Implements &quot; <A
0N/A * HREF="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/">Exclusive XML
0N/A * Canonicalization, Version 1.0 </A>&quot; <BR />
0N/A * Credits: During restructuring of the Canonicalizer framework, Ren??
0N/A * Kollmorgen from Software AG submitted an implementation of ExclC14n which
0N/A * fitted into the old architecture and which based heavily on my old (and slow)
0N/A * implementation of "Canonical XML". A big "thank you" to Ren?? for this.
0N/A * <BR />
0N/A * <i>THIS </i> implementation is a complete rewrite of the algorithm.
0N/A *
0N/A * @author Christian Geuer-Pollmann <geuerp@apache.org>
661N/A * @version $Revision: 1.5 $
0N/A * @see <a href="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/ Exclusive#">
0N/A * XML Canonicalization, Version 1.0</a>
0N/A */
0N/Apublic abstract class Canonicalizer20010315Excl extends CanonicalizerBase {
0N/A /**
0N/A * This Set contains the names (Strings like "xmlns" or "xmlns:foo") of
0N/A * the inclusive namespaces.
0N/A */
661N/A TreeSet _inclusiveNSSet = new TreeSet();
0N/A static final String XMLNS_URI=Constants.NamespaceSpecNS;
0N/A final SortedSet result = new TreeSet(COMPARE);
0N/A /**
0N/A * Constructor Canonicalizer20010315Excl
0N/A *
0N/A * @param includeComments
0N/A */
0N/A public Canonicalizer20010315Excl(boolean includeComments) {
0N/A super(includeComments);
0N/A }
0N/A
0N/A /**
0N/A * Method engineCanonicalizeSubTree
0N/A * @inheritDoc
0N/A * @param rootNode
0N/A *
0N/A * @throws CanonicalizationException
0N/A */
0N/A public byte[] engineCanonicalizeSubTree(Node rootNode)
0N/A throws CanonicalizationException {
0N/A return this.engineCanonicalizeSubTree(rootNode, "",null);
0N/A }
0N/A /**
0N/A * Method engineCanonicalizeSubTree
0N/A * @inheritDoc
0N/A * @param rootNode
0N/A * @param inclusiveNamespaces
0N/A *
0N/A * @throws CanonicalizationException
0N/A */
0N/A public byte[] engineCanonicalizeSubTree(Node rootNode,
0N/A String inclusiveNamespaces) throws CanonicalizationException {
0N/A return this.engineCanonicalizeSubTree(rootNode, inclusiveNamespaces,null);
0N/A }
0N/A /**
0N/A * Method engineCanonicalizeSubTree
0N/A * @param rootNode
0N/A * @param inclusiveNamespaces
0N/A * @param excl A element to exclude from the c14n process.
0N/A * @return the rootNode c14n.
0N/A * @throws CanonicalizationException
0N/A */
0N/A public byte[] engineCanonicalizeSubTree(Node rootNode,
0N/A String inclusiveNamespaces,Node excl) throws CanonicalizationException {
0N/A this._inclusiveNSSet = (TreeSet)InclusiveNamespaces
0N/A .prefixStr2Set(inclusiveNamespaces);
0N/A return super.engineCanonicalizeSubTree(rootNode,excl);
0N/A }
0N/A /**
0N/A *
0N/A * @param rootNode
0N/A * @param inclusiveNamespaces
0N/A * @return the rootNode c14n.
0N/A * @throws CanonicalizationException
0N/A */
0N/A public byte[] engineCanonicalize(XMLSignatureInput rootNode,
0N/A String inclusiveNamespaces) throws CanonicalizationException {
0N/A this._inclusiveNSSet = (TreeSet)InclusiveNamespaces
0N/A .prefixStr2Set(inclusiveNamespaces);
0N/A return super.engineCanonicalize(rootNode);
0N/A }
0N/A
0N/A /**
0N/A * Method handleAttributesSubtree
0N/A * @inheritDoc
0N/A * @param E
0N/A * @throws CanonicalizationException
0N/A */
0N/A Iterator handleAttributesSubtree(Element E,NameSpaceSymbTable ns)
0N/A throws CanonicalizationException {
0N/A // System.out.println("During the traversal, I encountered " +
0N/A // XMLUtils.getXPath(E));
0N/A // result will contain the attrs which have to be outputted
0N/A SortedSet result = this.result;
0N/A result.clear();
0N/A NamedNodeMap attrs=null;
0N/A
0N/A int attrsLength = 0;
0N/A if (E.hasAttributes()) {
0N/A attrs = E.getAttributes();
0N/A attrsLength = attrs.getLength();
0N/A }
0N/A //The prefix visibly utilized(in the attribute or in the name) in the element
0N/A SortedSet visiblyUtilized =(SortedSet) _inclusiveNSSet.clone();
0N/A
0N/A for (int i = 0; i < attrsLength; i++) {
0N/A Attr N = (Attr) attrs.item(i);
0N/A
661N/A if (XMLNS_URI!=N.getNamespaceURI()) {
0N/A //Not a namespace definition.
0N/A //The Element is output element, add his prefix(if used) to visibyUtilized
0N/A String prefix = N.getPrefix();
0N/A if ( (prefix != null) && (!prefix.equals(XML) && !prefix.equals(XMLNS)) ) {
0N/A visiblyUtilized.add(prefix);
0N/A }
0N/A //Add to the result.
0N/A result.add(N);
0N/A continue;
0N/A }
661N/A String NName=N.getLocalName();
661N/A String NNodeValue=N.getNodeValue();
0N/A
0N/A if (ns.addMapping(NName, NNodeValue,N)) {
0N/A //New definition check if it is relative.
0N/A if (C14nHelper.namespaceIsRelative(NNodeValue)) {
0N/A Object exArgs[] = {E.getTagName(), NName,
0N/A N.getNodeValue()};
0N/A throw new CanonicalizationException(
0N/A "c14n.Canonicalizer.RelativeNamespace", exArgs);
0N/A }
0N/A }
0N/A }
661N/A String prefix;
0N/A if (E.getNamespaceURI() != null) {
661N/A prefix = E.getPrefix();
0N/A if ((prefix == null) || (prefix.length() == 0)) {
661N/A prefix=XMLNS;
0N/A }
661N/A
0N/A } else {
661N/A prefix=XMLNS;
0N/A }
661N/A visiblyUtilized.add(prefix);
0N/A
0N/A //This can be optimezed by I don't have time
0N/A Iterator it=visiblyUtilized.iterator();
0N/A while (it.hasNext()) {
0N/A String s=(String)it.next();
0N/A Attr key=ns.getMapping(s);
0N/A if (key==null) {
0N/A continue;
0N/A }
0N/A result.add(key);
0N/A }
0N/A
0N/A return result.iterator();
0N/A }
0N/A
0N/A /**
0N/A * Method engineCanonicalizeXPathNodeSet
0N/A * @inheritDoc
0N/A * @param xpathNodeSet
0N/A * @param inclusiveNamespaces
0N/A * @throws CanonicalizationException
0N/A */
0N/A public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet,
0N/A String inclusiveNamespaces) throws CanonicalizationException {
0N/A
0N/A
0N/A this._inclusiveNSSet = (TreeSet)InclusiveNamespaces
0N/A .prefixStr2Set(inclusiveNamespaces);
0N/A return super.engineCanonicalizeXPathNodeSet(xpathNodeSet);
0N/A
0N/A }
0N/A
0N/A /**
0N/A * @inheritDoc
0N/A * @param E
0N/A * @throws CanonicalizationException
0N/A */
0N/A final Iterator handleAttributes(Element E, NameSpaceSymbTable ns)
0N/A throws CanonicalizationException {
0N/A // result will contain the attrs which have to be outputted
0N/A SortedSet result = this.result;
0N/A result.clear();
0N/A NamedNodeMap attrs = null;
0N/A int attrsLength = 0;
0N/A if (E.hasAttributes()) {
0N/A attrs = E.getAttributes();
0N/A attrsLength = attrs.getLength();
0N/A }
0N/A //The prefix visibly utilized(in the attribute or in the name) in the element
0N/A Set visiblyUtilized =null;
0N/A //It's the output selected.
661N/A boolean isOutputElement=isVisibleDO(E,ns.getLevel())==1;
0N/A if (isOutputElement) {
0N/A visiblyUtilized = (Set) this._inclusiveNSSet.clone();
0N/A }
0N/A
0N/A for (int i = 0; i < attrsLength; i++) {
0N/A Attr N = (Attr) attrs.item(i);
661N/A
0N/A
661N/A if (XMLNS_URI!=N.getNamespaceURI()) {
661N/A if ( !isVisible(N) ) {
661N/A //The node is not in the nodeset(if there is a nodeset)
661N/A continue;
661N/A }
0N/A //Not a namespace definition.
0N/A if (isOutputElement) {
0N/A //The Element is output element, add his prefix(if used) to visibyUtilized
0N/A String prefix = N.getPrefix();
0N/A if ((prefix != null) && (!prefix.equals(XML) && !prefix.equals(XMLNS)) ){
0N/A visiblyUtilized.add(prefix);
0N/A }
0N/A //Add to the result.
0N/A result.add(N);
0N/A }
0N/A continue;
0N/A }
661N/A String NName=N.getLocalName();
661N/A if (isOutputElement && !isVisible(N) && NName!=XMLNS) {
661N/A ns.removeMappingIfNotRender(NName);
661N/A continue;
661N/A }
661N/A String NNodeValue=N.getNodeValue();
661N/A
661N/A if (!isOutputElement && isVisible(N) && _inclusiveNSSet.contains(NName) && !ns.removeMappingIfRender(NName)) {
661N/A Node n=ns.addMappingAndRender(NName,NNodeValue,N);
661N/A if (n!=null) {
661N/A result.add(n);
661N/A if (C14nHelper.namespaceIsRelative(N)) {
661N/A Object exArgs[] = { E.getTagName(), NName, N.getNodeValue() };
661N/A throw new CanonicalizationException(
661N/A "c14n.Canonicalizer.RelativeNamespace", exArgs);
661N/A }
661N/A }
661N/A }
661N/A
0N/A
0N/A
0N/A if (ns.addMapping(NName, NNodeValue,N)) {
0N/A //New definiton check if it is relative
0N/A if (C14nHelper.namespaceIsRelative(NNodeValue)) {
0N/A Object exArgs[] = {E.getTagName(), NName,
0N/A N.getNodeValue()};
0N/A throw new CanonicalizationException(
0N/A "c14n.Canonicalizer.RelativeNamespace", exArgs);
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (isOutputElement) {
0N/A //The element is visible, handle the xmlns definition
0N/A Attr xmlns = E.getAttributeNodeNS(XMLNS_URI, XMLNS);
0N/A if ((xmlns!=null) && (!isVisible(xmlns))) {
0N/A //There is a definition but the xmlns is not selected by the xpath.
0N/A //then xmlns=""
0N/A ns.addMapping(XMLNS,"",nullNode);
0N/A }
0N/A
0N/A if (E.getNamespaceURI() != null) {
0N/A String prefix = E.getPrefix();
0N/A if ((prefix == null) || (prefix.length() == 0)) {
0N/A visiblyUtilized.add(XMLNS);
0N/A } else {
0N/A visiblyUtilized.add( prefix);
0N/A }
0N/A } else {
0N/A visiblyUtilized.add(XMLNS);
0N/A }
0N/A //This can be optimezed by I don't have time
0N/A //visiblyUtilized.addAll(this._inclusiveNSSet);
0N/A Iterator it=visiblyUtilized.iterator();
0N/A while (it.hasNext()) {
0N/A String s=(String)it.next();
0N/A Attr key=ns.getMapping(s);
0N/A if (key==null) {
0N/A continue;
0N/A }
0N/A result.add(key);
0N/A }
0N/A }
0N/A
0N/A return result.iterator();
0N/A }
661N/A void circumventBugIfNeeded(XMLSignatureInput input) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException {
661N/A if (!input.isNeedsToBeExpanded() || _inclusiveNSSet.isEmpty())
661N/A return;
661N/A Document doc = null;
661N/A if (input.getSubNode() != null) {
661N/A doc=XMLUtils.getOwnerDocument(input.getSubNode());
661N/A } else {
661N/A doc=XMLUtils.getOwnerDocument(input.getNodeSet());
661N/A }
661N/A
661N/A XMLUtils.circumventBug2650(doc);
661N/A }
0N/A}