Adding some code coverage tests for the utils package.
git-svn-id: https://svn.apache.org/repos/asf/santuario/xml-security-java/trunk@1877416 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/xml/security/signature/XMLSignature.java b/src/main/java/org/apache/xml/security/signature/XMLSignature.java
index 2387f8b..b650877 100644
--- a/src/main/java/org/apache/xml/security/signature/XMLSignature.java
+++ b/src/main/java/org/apache/xml/security/signature/XMLSignature.java
@@ -29,9 +29,7 @@
import javax.crypto.SecretKey;
import org.apache.xml.security.algorithms.SignatureAlgorithm;
-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.exceptions.XMLSecurityException;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.X509Data;
@@ -793,13 +791,7 @@
this.setSignatureValueElement(sa.sign());
} catch (XMLSignatureException ex) {
throw ex;
- } catch (CanonicalizationException ex) {
- throw new XMLSignatureException(ex);
- } catch (InvalidCanonicalizerException ex) {
- throw new XMLSignatureException(ex);
- } catch (XMLSecurityException ex) {
- throw new XMLSignatureException(ex);
- } catch (IOException ex) {
+ } catch (XMLSecurityException | IOException ex) {
throw new XMLSignatureException(ex);
}
}
diff --git a/src/main/java/org/apache/xml/security/transforms/implementations/TransformXPath.java b/src/main/java/org/apache/xml/security/transforms/implementations/TransformXPath.java
index facf4a3..32f4e2c 100644
--- a/src/main/java/org/apache/xml/security/transforms/implementations/TransformXPath.java
+++ b/src/main/java/org/apache/xml/security/transforms/implementations/TransformXPath.java
@@ -93,7 +93,7 @@
String str = XMLUtils.getStrFromNode(xpathnode);
input.setNeedsToBeExpanded(needsCircumvent(str));
- XPathFactory xpathFactory = XPathFactory.newInstance();
+ XPathFactory xpathFactory = getXPathFactory();
XPathAPI xpathAPIInstance = xpathFactory.newXPathAPI();
input.addNodeFilter(new XPathNodeFilter(xpathElement, xpathnode, str, xpathAPIInstance));
input.setNodeSet(true);
@@ -103,6 +103,10 @@
}
}
+ protected XPathFactory getXPathFactory() {
+ return XPathFactory.newInstance();
+ }
+
/**
* @param str
* @return true if needs to be circumvent for bug.
diff --git a/src/main/java/org/apache/xml/security/utils/ElementProxy.java b/src/main/java/org/apache/xml/security/utils/ElementProxy.java
index 5b02f05..4e39b9e 100644
--- a/src/main/java/org/apache/xml/security/utils/ElementProxy.java
+++ b/src/main/java/org/apache/xml/security/utils/ElementProxy.java
@@ -206,7 +206,7 @@
}
protected Text createText(String text) {
- return this.wrappedDoc.createTextNode(text);
+ return getDocument().createTextNode(text);
}
/**
@@ -286,15 +286,7 @@
*/
public void addBase64Element(byte[] bytes, String localname) {
if (bytes != null) {
- Element el = XMLUtils.createElementInSignatureSpace(getDocument(), localname);
- Text text = getDocument().createTextNode(XMLUtils.encodeToString(bytes));
-
- el.appendChild(text);
-
- appendSelf(el);
- if (!XMLUtils.ignoreLineBreaks()) {
- appendSelf(createText("\n"));
- }
+ addTextElement(XMLUtils.encodeToString(bytes), localname);
}
}
diff --git a/src/main/java/org/apache/xml/security/utils/EncryptionElementProxy.java b/src/main/java/org/apache/xml/security/utils/EncryptionElementProxy.java
deleted file mode 100644
index 9accf3a..0000000
--- a/src/main/java/org/apache/xml/security/utils/EncryptionElementProxy.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * 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.utils;
-
-
-import org.apache.xml.security.exceptions.XMLSecurityException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * This is the base object for all objects which map directly to an Element from
- * the xenc spec.
- *
- */
-public abstract class EncryptionElementProxy extends ElementProxy {
-
- /**
- * Constructor EncryptionElementProxy
- *
- * @param doc
- */
- public EncryptionElementProxy(Document doc) {
- super(doc);
- }
-
- /**
- * Constructor EncryptionElementProxy
- *
- * @param element
- * @param baseURI
- * @throws XMLSecurityException
- */
- public EncryptionElementProxy(Element element, String baseURI)
- throws XMLSecurityException {
- super(element, baseURI);
- }
-
- /** {@inheritDoc} */
- public final String getBaseNamespace() {
- return EncryptionConstants.EncryptionSpecNS;
- }
-}
diff --git a/src/main/java/org/apache/xml/security/utils/JDKXPathAPI.java b/src/main/java/org/apache/xml/security/utils/JDKXPathAPI.java
index c455149..09e424f 100644
--- a/src/main/java/org/apache/xml/security/utils/JDKXPathAPI.java
+++ b/src/main/java/org/apache/xml/security/utils/JDKXPathAPI.java
@@ -33,7 +33,7 @@
/**
* An implementation for XPath evaluation that uses the JDK API.
*/
-public class JDKXPathAPI implements XPathAPI {
+class JDKXPathAPI implements XPathAPI {
private XPathFactory xpf;
diff --git a/src/main/java/org/apache/xml/security/utils/UnsyncByteArrayInputStream.java b/src/main/java/org/apache/xml/security/utils/UnsyncByteArrayInputStream.java
index ff6cd1e..7d18783 100644
--- a/src/main/java/org/apache/xml/security/utils/UnsyncByteArrayInputStream.java
+++ b/src/main/java/org/apache/xml/security/utils/UnsyncByteArrayInputStream.java
@@ -56,9 +56,7 @@
* the byte array to stream over.
*/
public UnsyncByteArrayInputStream(byte[] buf) {
- this.mark = 0;
- this.buf = buf;
- this.count = buf.length;
+ this(buf, 0, buf.length);
}
/**
diff --git a/src/main/java/org/apache/xml/security/utils/XMLUtils.java b/src/main/java/org/apache/xml/security/utils/XMLUtils.java
index f145753..6a80d1d 100644
--- a/src/main/java/org/apache/xml/security/utils/XMLUtils.java
+++ b/src/main/java/org/apache/xml/security/utils/XMLUtils.java
@@ -472,26 +472,6 @@
}
/**
- * Method createDSctx
- *
- * @param doc
- * @param prefix
- * @param namespace
- * @return the element.
- */
- public static Element createDSctx(Document doc, String prefix, String namespace) {
- if (prefix == null || prefix.trim().length() == 0) {
- throw new IllegalArgumentException("You must supply a prefix");
- }
-
- Element ctx = doc.createElementNS(null, "namespaceContext");
-
- ctx.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:" + prefix.trim(), namespace);
-
- return ctx;
- }
-
- /**
* Method addReturnToElement
*
* @param e
@@ -842,25 +822,6 @@
}
/**
- * Returns the attribute value for the attribute with the specified name.
- * Returns null if there is no such attribute, or
- * the empty string if the attribute value is empty.
- *
- * <p>This works around a limitation of the DOM
- * <code>Element.getAttributeNode</code> method, which does not distinguish
- * between an unspecified attribute and an attribute with a value of
- * "" (it returns "" for both cases).
- *
- * @param elem the element containing the attribute
- * @param name the name of the attribute
- * @return the attribute value (may be null if unspecified)
- */
- public static String getAttributeValue(Element elem, String name) {
- Attr attr = elem.getAttributeNodeNS(null, name);
- return (attr == null) ? null : attr.getValue();
- }
-
- /**
* This method is a tree-search to help prevent against wrapping attacks. It checks that no
* two Elements have ID Attributes that match the "value" argument, if this is the case then
* "false" is returned. Note that a return value of "true" does not necessarily mean that
diff --git a/src/main/java/org/apache/xml/security/utils/XPathFactory.java b/src/main/java/org/apache/xml/security/utils/XPathFactory.java
index 84b92c2..ebd1504 100644
--- a/src/main/java/org/apache/xml/security/utils/XPathFactory.java
+++ b/src/main/java/org/apache/xml/security/utils/XPathFactory.java
@@ -45,11 +45,8 @@
* Get a new XPathFactory instance
*/
public static XPathFactory newInstance() {
- if (!xalanInstalled) {
- return new JDKXPathFactory();
- }
// Xalan is available
- if (XalanXPathAPI.isInstalled()) {
+ if (xalanInstalled && XalanXPathAPI.isInstalled()) {
return new XalanXPathFactory();
}
// Some problem was encountered in fixing up the Xalan FunctionTable so fall back to the
diff --git a/src/main/java/org/apache/xml/security/utils/XalanXPathAPI.java b/src/main/java/org/apache/xml/security/utils/XalanXPathAPI.java
index 45bfd82..bec20bc 100644
--- a/src/main/java/org/apache/xml/security/utils/XalanXPathAPI.java
+++ b/src/main/java/org/apache/xml/security/utils/XalanXPathAPI.java
@@ -42,7 +42,7 @@
* An implementation of XPathAPI using Xalan. This supports the "here()" function defined in the digital
* signature spec.
*/
-public class XalanXPathAPI implements XPathAPI {
+class XalanXPathAPI implements XPathAPI {
private static final org.slf4j.Logger LOG =
org.slf4j.LoggerFactory.getLogger(XalanXPathAPI.class);
diff --git a/src/test/java/org/apache/xml/security/test/dom/signature/CreateSignatureTest.java b/src/test/java/org/apache/xml/security/test/dom/signature/CreateSignatureTest.java
index d97a8f8..04d8f16 100644
--- a/src/test/java/org/apache/xml/security/test/dom/signature/CreateSignatureTest.java
+++ b/src/test/java/org/apache/xml/security/test/dom/signature/CreateSignatureTest.java
@@ -217,6 +217,59 @@
}
@org.junit.jupiter.api.Test
+ public void testXPathSignature() throws Exception {
+ Document doc = TestUtils.newDocument();
+ doc.appendChild(doc.createComment(" Comment before "));
+ Element root = doc.createElementNS("", "RootElement");
+
+ doc.appendChild(root);
+ root.appendChild(doc.createTextNode("Some simple text\n"));
+
+ // Sign
+ XMLSignature sig =
+ new XMLSignature(doc, null, XMLSignature.ALGO_ID_SIGNATURE_RSA);
+ root.appendChild(sig.getElement());
+
+ ObjectContainer object = new ObjectContainer(doc);
+ object.setId("object-1");
+ object.setMimeType("text/plain");
+ object.setEncoding("http://www.w3.org/2000/09/xmldsig#base64");
+ object.appendChild(doc.createTextNode("SSBhbSB0aGUgdGV4dC4="));
+ sig.appendObject(object);
+
+ Transforms transforms = new Transforms(doc);
+ XPathContainer xpathC = new XPathContainer(doc);
+ xpathC.setXPath("ancestor-or-self::dsig-xpath:Object");
+ xpathC.setXPathNamespaceContext("dsig-xpath", Transforms.TRANSFORM_XPATH);
+
+ Element node = xpathC.getElement();
+ transforms.addTransform(Transforms.TRANSFORM_XPATH, node);
+ sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
+
+ sig.sign(kp.getPrivate());
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ XMLUtils.outputDOMc14nWithComments(doc, bos);
+ String signedDoc = new String(bos.toByteArray());
+
+ // Now Verify
+ try (InputStream is = new ByteArrayInputStream(signedDoc.getBytes())) {
+ doc = XMLUtils.read(is, false);
+ }
+
+ XPathFactory xpf = XPathFactory.newInstance();
+ XPath xpath = xpf.newXPath();
+ xpath.setNamespaceContext(new DSNamespaceContext());
+
+ String expression = "//ds:Signature[1]";
+ Element sigElement =
+ (Element) xpath.evaluate(expression, doc, XPathConstants.NODE);
+
+ XMLSignature signature = new XMLSignature(sigElement, "");
+ assertTrue(signature.checkSignatureValue(kp.getPublic()));
+ }
+
+ @org.junit.jupiter.api.Test
public void testCanonicalizedOctetStream() throws Exception {
String signedXML = doSign();
diff --git a/src/test/java/org/apache/xml/security/test/dom/utils/JDKXPathFactoryTest.java b/src/test/java/org/apache/xml/security/test/dom/utils/JDKXPathFactoryTest.java
new file mode 100644
index 0000000..e27400d
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/test/dom/utils/JDKXPathFactoryTest.java
@@ -0,0 +1,143 @@
+/**
+ * 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.utils;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.algorithms.SignatureAlgorithm;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.keys.keyresolver.KeyResolver;
+import org.apache.xml.security.signature.ObjectContainer;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.test.dom.DSNamespaceContext;
+import org.apache.xml.security.test.dom.TestUtils;
+import org.apache.xml.security.transforms.Transform;
+import org.apache.xml.security.transforms.Transforms;
+import org.apache.xml.security.transforms.implementations.TransformXPath;
+import org.apache.xml.security.transforms.params.XPathContainer;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.ElementProxy;
+import org.apache.xml.security.utils.I18n;
+import org.apache.xml.security.utils.JDKXPathFactory;
+import org.apache.xml.security.utils.XMLUtils;
+import org.apache.xml.security.utils.resolver.ResourceResolver;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test the JDKXPathFactory by adding a custom transform that hard-wires the use of JDKXPathFactory, instead of
+ * checking to see whether Xalan is on the classpath or not
+ */
+public class JDKXPathFactoryTest {
+
+ static org.slf4j.Logger LOG =
+ org.slf4j.LoggerFactory.getLogger(JDKXPathFactoryTest.class);
+
+ private KeyPair kp;
+
+ public JDKXPathFactoryTest() throws Exception {
+ // org.apache.xml.security.Init.init();
+ // Instead of calling Init.init(), instead initialize the library manually
+ I18n.init("en", "US");
+ ElementProxy.registerDefaultPrefixes();
+ SignatureAlgorithm.registerDefaultAlgorithms();
+ JCEMapper.registerDefaultAlgorithms();
+ Canonicalizer.registerDefaultAlgorithms();
+ ResourceResolver.registerDefaultResolvers();
+ KeyResolver.registerDefaultResolvers();
+
+ // Manually register TransformJDKXPath
+ Transform.register(Transforms.TRANSFORM_XPATH, TransformJDKXPath.class);
+
+ kp = KeyPairGenerator.getInstance("RSA").genKeyPair();
+ }
+
+ @org.junit.jupiter.api.Test
+ public void testXPathSignature() throws Exception {
+ Document doc = TestUtils.newDocument();
+ doc.appendChild(doc.createComment(" Comment before "));
+ Element root = doc.createElementNS("", "RootElement");
+
+ doc.appendChild(root);
+ root.appendChild(doc.createTextNode("Some simple text\n"));
+
+ // Sign
+ XMLSignature sig =
+ new XMLSignature(doc, null, XMLSignature.ALGO_ID_SIGNATURE_RSA);
+ root.appendChild(sig.getElement());
+
+ ObjectContainer object = new ObjectContainer(doc);
+ object.setId("object-1");
+ object.setMimeType("text/plain");
+ object.setEncoding("http://www.w3.org/2000/09/xmldsig#base64");
+ object.appendChild(doc.createTextNode("SSBhbSB0aGUgdGV4dC4="));
+ sig.appendObject(object);
+
+ Transforms transforms = new Transforms(doc);
+ XPathContainer xpathC = new XPathContainer(doc);
+ xpathC.setXPath("ancestor-or-self::dsig-xpath:Object");
+ xpathC.setXPathNamespaceContext("dsig-xpath", Transforms.TRANSFORM_XPATH);
+
+ Element node = xpathC.getElement();
+ transforms.addTransform(Transforms.TRANSFORM_XPATH, node);
+ sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
+
+ sig.sign(kp.getPrivate());
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ XMLUtils.outputDOMc14nWithComments(doc, bos);
+ String signedDoc = new String(bos.toByteArray());
+
+ // Now Verify
+ try (InputStream is = new ByteArrayInputStream(signedDoc.getBytes())) {
+ doc = XMLUtils.read(is, false);
+ }
+
+ XPathFactory xpf = XPathFactory.newInstance();
+ XPath xpath = xpf.newXPath();
+ xpath.setNamespaceContext(new DSNamespaceContext());
+
+ String expression = "//ds:Signature[1]";
+ Element sigElement =
+ (Element) xpath.evaluate(expression, doc, XPathConstants.NODE);
+
+ XMLSignature signature = new XMLSignature(sigElement, "");
+ assertTrue(signature.checkSignatureValue(kp.getPublic()));
+ }
+
+ public static class TransformJDKXPath extends TransformXPath {
+ @Override
+ protected org.apache.xml.security.utils.XPathFactory getXPathFactory() {
+ return new JDKXPathFactory();
+ }
+ }
+
+}
\ No newline at end of file