blob: 366cd81d0b70e58478a9116560e5b3548e5c52f4 [file] [log] [blame]
/**
* 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.test.dom.c14n.implementations;
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.xml.security.c14n.CanonicalizationException;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.c14n.InvalidCanonicalizerException;
import org.apache.xml.security.test.dom.DSNamespaceContext;
import org.apache.xml.security.utils.IgnoreAllErrorHandler;
import org.apache.xml.security.utils.JavaUtils;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* Unit test for
* {@link org.apache.xml.security.c14n.implementations.Canonicalizer11}
*/
public class Canonicalizer11Test {
static org.slf4j.Logger LOG =
org.slf4j.LoggerFactory.getLogger(Canonicalizer11Test.class);
static {
org.apache.xml.security.Init.init();
}
/** Field prefix */
private String prefix;
public Canonicalizer11Test() {
prefix = "src/test/resources/org/apache/xml/security/c14n/";
String basedir = System.getProperty("basedir");
if (basedir != null && !"".equals(basedir)) {
prefix = basedir + "/" + prefix;
}
}
/**
* 3.1 PIs, Comments, and Outside of Document Element
*
* @throws CanonicalizationException
* @throws FileNotFoundException
* @throws IOException
* @throws InvalidCanonicalizerException
* @throws ParserConfigurationException
* @throws SAXException
* @throws TransformerException
* @throws XPathExpressionException
*/
@org.junit.Test
public void test31withCommentsSubtree()
throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
String descri =
"3.1: PIs, Comments, and Outside of Document Element. (commented)";
String fileIn = prefix + "in/31_input.xml";
String fileRef = prefix + "in/31_c14n-comments.xml";
String fileOut = prefix + "out/xpath_31_output-comments.xml";
String c14nURI = Canonicalizer.ALGO_ID_C14N11_WITH_COMMENTS;
boolean validating = true;
String xpath = null;
assertTrue(descri,
c14nAndCompare(fileIn, fileRef, fileOut, c14nURI, validating, xpath));
}
/**
* 3.2 Whitespace in Document Content
*
* @throws CanonicalizationException
* @throws FileNotFoundException
* @throws IOException
* @throws InvalidCanonicalizerException
* @throws ParserConfigurationException
* @throws SAXException
* @see <A HREF="http://www.w3.org/TR/2001/PR-xml-c14n-20010119#Example-WhitespaceInContent">the example from the spec</A>
* @throws TransformerException
* @throws XPathExpressionException
*/
@org.junit.Test
public void test32subtree()
throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
String descri = "3.2 Whitespace in Document Content. (uncommented)";
String fileIn = prefix + "in/32_input.xml";
String fileRef = prefix + "in/32_c14n.xml";
String fileOut = prefix + "out/xpath_32_output.xml";
String c14nURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
boolean validating = true;
String xpath = null;
assertTrue(descri,
c14nAndCompare(fileIn, fileRef, fileOut, c14nURI, validating, xpath));
}
/**
* 3.3 Start and End Tags
*
* @throws CanonicalizationException
* @throws FileNotFoundException
* @throws IOException
* @throws InvalidCanonicalizerException
* @throws ParserConfigurationException
* @throws SAXException
* @see <A HREF="http://www.w3.org/TR/2001/PR-xml-c14n-20010119#Example-SETags">the example from the spec</A>
* @throws TransformerException
* @throws XPathExpressionException
*/
@org.junit.Test
public void test33subtree()
throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
String descri = "3.3 Start and End Tags. (uncommented)";
String fileIn = prefix + "in/33_input.xml";
String fileRef = prefix + "in/33_c14n.xml";
String fileOut = prefix + "out/xpath_33_output.xml";
String c14nURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
boolean validating = true;
String xpath = null; // Canonicalizer.XPATH_C14N_OMIT_COMMENTS_SINGLE_NODE;
assertTrue(descri,
c14nAndCompare(fileIn, fileRef, fileOut, c14nURI, validating, xpath));
}
/**
* 3.4 Character Modifications and Character References
*
* @throws CanonicalizationException
* @throws FileNotFoundException
* @throws IOException
* @throws InvalidCanonicalizerException
* @throws ParserConfigurationException
* @throws SAXException
* @see #test34validatingParser
* @see <A HREF="http://www.w3.org/TR/2001/PR-xml-c14n-20010119#Example-Chars">the example from the spec</A>
* @throws TransformerException
* @throws XPathExpressionException
*/
@org.junit.Test
public void test34()
throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
String descri =
"3.4 Character Modifications and Character References. (uncommented)";
String fileIn = prefix + "in/34_input.xml";
String fileRef = prefix + "in/34_c14n.xml";
String fileOut = prefix + "out/xpath_34_output.xml";
String c14nURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
boolean validating = false;
String xpath = null;
assertTrue(descri,
c14nAndCompare(fileIn, fileRef, fileOut, c14nURI, validating, xpath));
}
/**
* 3.5 Entity References
*
* @throws CanonicalizationException
* @throws FileNotFoundException
* @throws IOException
* @throws InvalidCanonicalizerException
* @throws ParserConfigurationException
* @throws SAXException
* @see <A HREF="http://www.w3.org/TR/2001/PR-xml-c14n-20010119#Example-Entities">the example from the spec</A>
* @throws TransformerException
* @throws XPathExpressionException
*/
@org.junit.Test
public void test35subtree()
throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
String descri = "3.5 Entity References. (uncommented)";
String fileIn = prefix + "in/35_input.xml";
String fileRef = prefix + "in/35_c14n.xml";
String fileOut = prefix + "out/xpath_35_output.xml";
String c14nURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
boolean validating = true;
String xpath = null;
assertTrue(descri,
c14nAndCompare(fileIn, fileRef, fileOut, c14nURI, validating, xpath));
}
/**
* 3.6 UTF-8 Encoding
*
* @throws CanonicalizationException
* @throws FileNotFoundException
* @throws IOException
* @throws InvalidCanonicalizerException
* @throws ParserConfigurationException
* @throws SAXException
* @see <A HREF="http://www.w3.org/TR/2001/PR-xml-c14n-20010119#Example-UTF8">the example from the spec</A>
* @throws TransformerException
* @throws XPathExpressionException
*/
@org.junit.Test
public void test36subtree()
throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
String descri = "3.6 UTF-8 Encoding. (uncommented)";
String fileIn = prefix + "in/36_input.xml";
String fileRef = prefix + "in/36_c14n.xml";
String fileOut = prefix + "out/xpath_36_output.xml";
String c14nURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
boolean validating = true;
String xpath = null;
assertTrue(descri,
c14nAndCompare(fileIn, fileRef, fileOut, c14nURI, validating, xpath));
}
/**
* 3.7 Document Subsets
*
* @throws CanonicalizationException
* @throws FileNotFoundException
* @throws IOException
* @throws InvalidCanonicalizerException
* @throws ParserConfigurationException
* @throws SAXException
* @see <A HREF="http://www.w3.org/TR/2001/PR-xml-c14n-20010119#Example-DocSubsets">the example from the spec</A>
* @throws TransformerException
* @throws XPathExpressionException
*/
@org.junit.Test
public void test37()
throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
String descri = "3.7 Document Subsets. (uncommented)";
String fileIn = prefix + "in/37_input.xml";
String fileRef = prefix + "in/37_c14n.xml";
String fileOut = prefix + "out/xpath_37_output.xml";
String c14nURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
boolean validating = true;
Map<String, String> namespace = new HashMap<>();
namespace.put("ietf", "http://www.ietf.org");
String xpath =
"(//. | //@* | //namespace::*)"
+ "[ "
+ "self::ietf:e1 or "
+ "(parent::ietf:e1 and not(self::text() or self::e2)) or "
+ "count(id(\"E3\")|ancestor-or-self::node()) = count(ancestor-or-self::node()) "
+ "]";
assertTrue(descri,
c14nAndCompare(fileIn, fileRef, fileOut, c14nURI, validating, xpath, namespace));
}
/**
* 3.8 Document Subsets and XML Attributes
*
* @throws CanonicalizationException
* @throws FileNotFoundException
* @throws IOException
* @throws InvalidCanonicalizerException
* @throws ParserConfigurationException
* @throws SAXException
* @throws TransformerException
* @throws XPathExpressionException
*/
@org.junit.Test
public void test38()
throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
String descri = "3.8 Document Subsets and XML Attributes (uncommented)";
String fileIn = prefix + "in/38_input.xml";
String fileRef = prefix + "in/38_c14n.xml";
String fileOut = prefix + "out/xpath_38_output.xml";
String c14nURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
boolean validating = true;
Map<String, String> namespace = new HashMap<>();
namespace.put("ietf", "http://www.ietf.org");
String xpath =
"(//. | //@* | //namespace::*)"
+ "[ "
+ "self::ietf:e1 or "
+ "(parent::ietf:e1 and not(self::text() or self::e2)) or "
+ "count(id(\"E3\")|ancestor-or-self::node()) = count(ancestor-or-self::node()) "
+ "]";
assertTrue(descri,
c14nAndCompare(fileIn, fileRef, fileOut, c14nURI, validating, xpath, namespace));
}
private boolean c14nAndCompare(
String fileIn,
String fileRef,
String fileOut,
String c14nURI,
boolean validating,
String xpath
) throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
Map<String, String> namespace = new HashMap<>();
return c14nAndCompare(fileIn, fileRef, fileOut,
c14nURI, validating, xpath, namespace);
}
private boolean c14nAndCompare(
String fileIn,
String fileRef,
String fileOut,
String c14nURI,
boolean validating,
String xpath,
Map<String, String> namespaces
) throws IOException, FileNotFoundException, SAXException,
ParserConfigurationException, CanonicalizationException,
InvalidCanonicalizerException, TransformerException, XPathExpressionException {
DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(validating, false);
// throw away all warnings and errors
documentBuilder.setErrorHandler(new IgnoreAllErrorHandler());
// org.xml.sax.EntityResolver resolver = new TestVectorResolver();
// documentBuilder.setEntityResolver(resolver);
// Document doc = documentBuilder.parse(resolver.resolveEntity(null, fileIn));
Document doc = documentBuilder.parse(fileIn);
Canonicalizer c14n = Canonicalizer.getInstance(c14nURI);
byte c14nBytes[] = null;
if (xpath == null) {
c14nBytes = c14n.canonicalizeSubtree(doc);
} else {
NodeList nl = null;
XPathFactory xpf = XPathFactory.newInstance();
XPath xPath = xpf.newXPath();
DSNamespaceContext namespaceContext =
new DSNamespaceContext(namespaces);
xPath.setNamespaceContext(namespaceContext);
nl = (NodeList)xPath.evaluate(xpath, doc, XPathConstants.NODESET);
c14nBytes = c14n.canonicalizeXPathNodeSet(nl);
}
// org.xml.sax.InputSource refIs = resolver.resolveEntity(null, fileRef);
// byte refBytes[] = JavaUtils.getBytesFromStream(refIs.getByteStream());
byte refBytes[] = JavaUtils.getBytesFromFile(fileRef);
// if everything is OK, result is true; we do a binary compare, byte by byte
boolean result = java.security.MessageDigest.isEqual(refBytes, c14nBytes);
if (!result) {
File f = new File(fileOut);
if (!f.exists()) {
File parent = new File(f.getParent());
parent.mkdirs();
f.createNewFile();
}
FileOutputStream fos = new FileOutputStream(f);
fos.write(c14nBytes);
LOG.debug("Wrote erroneous result to file " + f.toURI().toURL().toString());
assertEquals(new String(refBytes), new String(c14nBytes));
fos.close();
}
return result;
}
}