8305972: Update XML Security for Java to 3.0.2

Reviewed-by: mullan
(cherry picked from commit f0aebc8141)
This commit is contained in:
Weijun Wang
2023-05-19 17:46:41 +00:00
committed by Vitaly Provodin
parent a5213b8796
commit aa4a00e69c
38 changed files with 1040 additions and 260 deletions

View File

@@ -1001,6 +1001,23 @@ jdk.xml.dsig.secureValidationPolicy=\
noDuplicateIds,\
noRetrievalMethodLoops
#
# Support for the here() function
#
# This security property determines whether the here() XPath function is
# supported in XML Signature generation and verification.
#
# If this property is set to false, the here() function is not supported.
# Generating an XML Signature that uses the here() function will throw an
# XMLSignatureException. Validating an existing XML Signature that uses the
# here() function will also throw an XMLSignatureException.
#
# The default value for this property is true.
#
# Note: This property is currently used by the JDK Reference implementation.
# It is not guaranteed to be examined and used by other implementations.
#
#jdk.xml.dsig.hereFunctionSupported=true
#
# Deserialization JVM-wide filter factory

View File

@@ -96,6 +96,8 @@ grant codeBase "jrt:/java.xml.crypto" {
"removeProviderProperty.XMLDSig";
permission java.security.SecurityPermission
"com.sun.org.apache.xml.internal.security.register";
permission java.security.SecurityPermission
"getProperty.jdk.xml.dsig.hereFunctionSupported";
permission java.security.SecurityPermission
"getProperty.jdk.xml.dsig.secureValidationPolicy";
permission java.lang.RuntimePermission

View File

@@ -209,6 +209,14 @@ public class JCEMapper {
XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160,
new Algorithm("EC", "RIPEMD160withECDSA", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519,
new Algorithm("Ed25519", "Ed25519", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448,
new Algorithm("Ed448", "Ed448", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5,
new Algorithm("", "HmacMD5", "Mac", 0, 0)

View File

@@ -31,10 +31,7 @@ import java.security.spec.AlgorithmParameterSpec;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac;
import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA;
import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureDSA;
import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA;
import com.sun.org.apache.xml.internal.security.algorithms.implementations.*;
import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException;
import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
@@ -496,6 +493,12 @@ public class SignatureAlgorithm extends Algorithm {
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160, SignatureECDSA.SignatureECDSARIPEMD160.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519, SignatureEDDSA.SignatureEd25519.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448, SignatureEDDSA.SignatureEd448.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5, IntegrityHmac.IntegrityHmacMD5.class
);

View File

@@ -30,7 +30,6 @@ import java.math.BigInteger;
import java.security.interfaces.ECPublicKey;
import java.security.spec.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public final class ECDSAUtils {
@@ -786,9 +785,7 @@ public final class ECDSAUtils {
field = ecFieldF2m.getReductionPolynomial();
}
Iterator<ECCurveDefinition> ecCurveDefinitionIterator = ecCurveDefinitions.iterator();
while (ecCurveDefinitionIterator.hasNext()) {
ECCurveDefinition ecCurveDefinition = ecCurveDefinitionIterator.next();
for (ECCurveDefinition ecCurveDefinition : ecCurveDefinitions) {
String oid = ecCurveDefinition.equals(field, a, b, affineX, affineY, order, h);
if (oid != null) {
return oid;
@@ -798,9 +795,7 @@ public final class ECDSAUtils {
}
public static ECCurveDefinition getECCurveDefinition(String oid) {
Iterator<ECCurveDefinition> ecCurveDefinitionIterator = ecCurveDefinitions.iterator();
while (ecCurveDefinitionIterator.hasNext()) {
ECCurveDefinition ecCurveDefinition = ecCurveDefinitionIterator.next();
for (ECCurveDefinition ecCurveDefinition : ecCurveDefinitions) {
if (ecCurveDefinition.getOid().equals(oid)) {
return ecCurveDefinition;
}

View File

@@ -0,0 +1,228 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/**
* 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 com.sun.org.apache.xml.internal.security.algorithms.implementations;
import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi;
import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import java.io.IOException;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
/**
*
*/
public abstract class SignatureEDDSA extends SignatureAlgorithmSpi {
private static final com.sun.org.slf4j.internal.Logger LOG =
com.sun.org.slf4j.internal.LoggerFactory.getLogger(SignatureEDDSA.class);
private final Signature signatureAlgorithm;
/**
* Constructor SignatureEDDSA
*
* @throws XMLSignatureException
*/
public SignatureEDDSA() throws XMLSignatureException {
this(null);
}
public SignatureEDDSA(Provider provider) throws XMLSignatureException {
String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
LOG.debug("Created SignatureEDDSA using {}", algorithmID);
try {
if (provider == null) {
String providerId = JCEMapper.getProviderId();
if (providerId == null) {
this.signatureAlgorithm = Signature.getInstance(algorithmID);
} else {
this.signatureAlgorithm = Signature.getInstance(algorithmID, providerId);
}
} else {
this.signatureAlgorithm = Signature.getInstance(algorithmID, provider);
}
} catch (NoSuchAlgorithmException | NoSuchProviderException ex) {
Object[] exArgs = { algorithmID, ex.getLocalizedMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs);
}
}
/** {@inheritDoc} */
protected void engineSetParameter(AlgorithmParameterSpec params)
throws XMLSignatureException {
try {
this.signatureAlgorithm.setParameter(params);
} catch (InvalidAlgorithmParameterException ex) {
throw new XMLSignatureException(ex);
}
}
/** {@inheritDoc} */
protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
try {
if (LOG.isDebugEnabled()) {
LOG.debug("Called SignatureEDDSA.verify() on " + XMLUtils.encodeToString(signature));
}
return this.signatureAlgorithm.verify(signature);
} catch (SignatureException ex) {
throw new XMLSignatureException(ex);
}
}
/** {@inheritDoc} */
protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
engineInitVerify(publicKey, signatureAlgorithm);
}
/** {@inheritDoc} */
protected byte[] engineSign() throws XMLSignatureException {
try {
return this.signatureAlgorithm.sign();
} catch (SignatureException ex) {
throw new XMLSignatureException(ex);
}
}
/** {@inheritDoc} */
protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
throws XMLSignatureException {
engineInitSign(privateKey, secureRandom, this.signatureAlgorithm);
}
/** {@inheritDoc} */
protected void engineInitSign(Key privateKey) throws XMLSignatureException {
engineInitSign(privateKey, (SecureRandom)null);
}
/** {@inheritDoc} */
protected void engineUpdate(byte[] input) throws XMLSignatureException {
try {
this.signatureAlgorithm.update(input);
} catch (SignatureException ex) {
throw new XMLSignatureException(ex);
}
}
/** {@inheritDoc} */
protected void engineUpdate(byte input) throws XMLSignatureException {
try {
this.signatureAlgorithm.update(input);
} catch (SignatureException ex) {
throw new XMLSignatureException(ex);
}
}
/** {@inheritDoc} */
protected void engineUpdate(byte[] buf, int offset, int len) throws XMLSignatureException {
try {
this.signatureAlgorithm.update(buf, offset, len);
} catch (SignatureException ex) {
throw new XMLSignatureException(ex);
}
}
/** {@inheritDoc} */
protected String engineGetJCEAlgorithmString() {
return this.signatureAlgorithm.getAlgorithm();
}
/** {@inheritDoc} */
protected String engineGetJCEProviderName() {
return this.signatureAlgorithm.getProvider().getName();
}
/** {@inheritDoc} */
protected void engineSetHMACOutputLength(int HMACOutputLength)
throws XMLSignatureException {
throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
}
/** {@inheritDoc} */
protected void engineInitSign(
Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
) throws XMLSignatureException {
throw new XMLSignatureException("algorithms.CannotUseAlgorithmParameterSpecOnEdDSA");
}
/**
* Class SignatureEd25519
*
*/
public static class SignatureEd25519 extends SignatureEDDSA {
/**
* Constructor SignatureEd25519
*
* @throws XMLSignatureException
*/
public SignatureEd25519() throws XMLSignatureException {
super();
}
public SignatureEd25519(Provider provider) throws XMLSignatureException {
super(provider);
}
/** {@inheritDoc} */
@Override
public String engineGetURI() {
return XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519;
}
}
/**
* Class SignatureEd448
*/
public static class SignatureEd448 extends SignatureEDDSA {
/**
* Constructor SignatureEd448
*
* @throws XMLSignatureException
*/
public SignatureEd448() throws XMLSignatureException {
super();
}
public SignatureEd448(Provider provider) throws XMLSignatureException {
super(provider);
}
/** {@inheritDoc} */
@Override
public String engineGetURI() {
return XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448;
}
}
}

View File

@@ -27,7 +27,6 @@ import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
@@ -458,13 +457,17 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
} while(true);
}
protected int isVisibleDO(Node currentNode, int level) {
protected int isVisibleDO(Node currentNode, int level)
throws CanonicalizationException {
if (nodeFilter != null) {
Iterator<NodeFilter> it = nodeFilter.iterator();
while (it.hasNext()) {
int i = it.next().isNodeIncludeDO(currentNode, level);
if (i != 1) {
return i;
for (NodeFilter filter : nodeFilter) {
try {
int i = filter.isNodeIncludeDO(currentNode, level);
if (i != 1) {
return i;
}
} catch (Exception e) {
throw new CanonicalizationException(e);
}
}
}
@@ -474,13 +477,17 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
return 1;
}
protected int isVisibleInt(Node currentNode) {
protected int isVisibleInt(Node currentNode)
throws CanonicalizationException {
if (nodeFilter != null) {
Iterator<NodeFilter> it = nodeFilter.iterator();
while (it.hasNext()) {
int i = it.next().isNodeInclude(currentNode);
if (i != 1) {
return i;
for (NodeFilter filter : nodeFilter) {
try {
int i = filter.isNodeInclude(currentNode);
if (i != 1) {
return i;
}
} catch (Exception e) {
throw new CanonicalizationException(e);
}
}
}
@@ -490,12 +497,15 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
return 1;
}
protected boolean isVisible(Node currentNode) {
protected boolean isVisible(Node currentNode) throws CanonicalizationException {
if (nodeFilter != null) {
Iterator<NodeFilter> it = nodeFilter.iterator();
while (it.hasNext()) {
if (it.next().isNodeInclude(currentNode) != 1) {
return false;
for (NodeFilter filter : nodeFilter) {
try {
if (filter.isNodeInclude(currentNode) != 1) {
return false;
}
} catch (Exception e) {
throw new CanonicalizationException(e);
}
}
}

View File

@@ -24,7 +24,6 @@ package com.sun.org.apache.xml.internal.security.c14n.implementations;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -50,7 +49,7 @@ public class NameSpaceSymbTable {
initialMap.put(XMLNS, ne);
}
/**The map betwen prefix-> entry table. */
/**The map between prefix-> entry table. */
private SymbMap symb;
/**The stacks for removing the definitions when doing pop.*/
@@ -58,7 +57,7 @@ public class NameSpaceSymbTable {
private boolean cloned = true;
/**
* Default constractor
* Default constructor
**/
public NameSpaceSymbTable() {
//Insert the default binding for xmlns.
@@ -75,9 +74,7 @@ public class NameSpaceSymbTable {
* @param result the list where to fill the unrendered xmlns definitions.
**/
public void getUnrenderedNodes(Collection<Attr> result) {
Iterator<NameSpaceSymbEntry> it = symb.entrySet().iterator();
while (it.hasNext()) {
NameSpaceSymbEntry n = it.next();
for (NameSpaceSymbEntry n : symb.entrySet()) {
//put them rendered?
if (!n.rendered && n.n != null) {
n = n.clone();
@@ -170,14 +167,14 @@ public class NameSpaceSymbTable {
symb.put(prefix, entry);
entry.rendered = true;
entry.lastrendered = entry.uri;
// Return the node for outputing.
// Return the node for outputting.
return entry.n;
}
/**
* Gets a definition without mark it as render.
* For render in exclusive c14n the namespaces in the include prefixes.
* @param prefix The prefix whose definition is neaded.
* @param prefix The prefix whose definition is needed.
* @return the attr to render, null if there is no need to render
**/
public Attr getMappingWithoutRendered(String prefix) {

View File

@@ -129,20 +129,16 @@ class XmlAttrStack {
}
}
if (!baseAttrs.isEmpty()) {
Iterator<Attr> it = col.iterator();
String base = null;
Attr baseAttr = null;
while (it.hasNext()) {
Attr n = it.next();
for (Attr n : col) {
if ("base".equals(n.getLocalName())) {
base = n.getValue();
baseAttr = n;
break;
}
}
it = baseAttrs.iterator();
while (it.hasNext()) {
Attr n = it.next();
for (Attr n : baseAttrs) {
if (base == null) {
base = n.getValue();
baseAttr = n;
@@ -162,9 +158,7 @@ class XmlAttrStack {
} else {
for (; size >= 0; size--) {
e = levels.get(size);
Iterator<Attr> it = e.nodes.iterator();
while (it.hasNext()) {
Attr n = it.next();
for (Attr n : e.nodes) {
if (!loa.containsKey(n.getName())) {
loa.put(n.getName(), n);
}
@@ -352,7 +346,7 @@ class XmlAttrStack {
// that from the input buffer else if the input buffer consists
// only of ".." and if the output buffer does not contain only
// the root slash "/", then move the ".." to the output buffer
// else delte it.; otherwise,
// else delete it.; otherwise,
} else if (".".equals(input)) {
input = "";
printStep("2D", output.toString(), input);

View File

@@ -59,7 +59,7 @@ public class MgmtData extends SignatureElementProxy implements KeyInfoContent {
/**
* Method getMgmtData
*
* @return the managment data
* @return the management data
*/
public String getMgmtData() {
return this.getTextFromTextChild();

View File

@@ -31,7 +31,6 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
@@ -283,10 +282,8 @@ public class RetrievalMethodResolver extends KeyResolverSpi {
}
private static Element getDocumentElement(Set<Node> set) {
Iterator<Node> it = set.iterator();
Element e = null;
while (it.hasNext()) {
Node currentNode = it.next();
for (Node currentNode : set) {
if (currentNode != null && Node.ELEMENT_NODE == currentNode.getNodeType()) {
e = (Element) currentNode;
break;
@@ -294,7 +291,7 @@ public class RetrievalMethodResolver extends KeyResolverSpi {
}
List<Node> parents = new ArrayList<>();
// Obtain all the parents of the elemnt
// Obtain all the parents of the element
while (e != null) {
parents.add(e);
Node n = e.getParentNode();

View File

@@ -128,6 +128,11 @@
JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA$SignatureECDSASHA512" />
<SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160"
JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA$SignatureECDSARIPEMD160" />
<SignatureAlgorithm URI="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519"
JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureEDDSA$SignatureEd25519" />
<SignatureAlgorithm URI="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448"
JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureEDDSA$SignatureEd448" />
<SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-md5"
JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacMD5" />

View File

@@ -28,7 +28,6 @@ import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -357,11 +356,8 @@ public class Manifest extends SignatureElementProxy {
currentRef.dereferenceURIandPerformTransforms(null);
Set<Node> nl = signedManifestNodes.getNodeSet();
Manifest referencedManifest = null;
Iterator<Node> nlIterator = nl.iterator();
while (nlIterator.hasNext()) {
Node n = nlIterator.next();
for (Node n : nl) {
if (n.getNodeType() == Node.ELEMENT_NODE
&& ((Element) n).getNamespaceURI().equals(Constants.SignatureSpecNS)
&& ((Element) n).getLocalName().equals(Constants._TAG_MANIFEST)

View File

@@ -22,6 +22,7 @@
*/
package com.sun.org.apache.xml.internal.security.signature;
import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
import org.w3c.dom.Node;
/**
@@ -37,7 +38,7 @@ public interface NodeFilter {
* -1 if the node and all it's child must not be output.
*
*/
int isNodeInclude(Node n);
int isNodeInclude(Node n) throws TransformationException;
/**
* Tells if a node must be output in a c14n.
@@ -50,6 +51,6 @@ public interface NodeFilter {
* 0 if node must not be output,
* -1 if the node and all it's child must not be output.
*/
int isNodeIncludeDO(Node n, int level);
int isNodeIncludeDO(Node n, int level) throws TransformationException;
}

View File

@@ -34,7 +34,7 @@ import org.w3c.dom.Node;
* Handles {@code &lt;ds:Object&gt;} elements
* {@code Object} {@link Element} supply facility which can contain any kind data
*
* $todo$ if we remove childen, the boolean values are not updated
* $todo$ if we remove children, the boolean values are not updated
*/
public class ObjectContainer extends SignatureElementProxy {

View File

@@ -49,7 +49,7 @@ public class SignatureProperty extends SignatureElementProxy {
}
/**
* Constructs {@link SignatureProperty} using sepcified {@code target} attribute and
* Constructs {@link SignatureProperty} using specified {@code target} attribute and
* {@code id} attribute
*
* @param doc the {@link Document} in which {@code XMLsignature} is placed

View File

@@ -38,7 +38,7 @@ public class VerifiedReference {
* @param valid Whether this Reference was successfully validated or not
* @param uri The URI of this Reference
* @param manifestReferences If this reference is a reference to a Manifest, this holds the list
* of verified referenes associated with this Manifest
* of verified references associated with this Manifest
*/
public VerifiedReference(boolean valid, String uri, List<VerifiedReference> manifestReferences) {
this.valid = valid;

View File

@@ -201,6 +201,14 @@ public final class XMLSignature extends SignatureElementProxy {
public static final String ALGO_ID_SIGNATURE_ECDSA_RIPEMD160 =
"http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160";
/**Signature - EDDSA ED25519 */
public static final String ALGO_ID_SIGNATURE_EDDSA_ED25519 =
"http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
/**Signature - EDDSA ED448 */
public static final String ALGO_ID_SIGNATURE_EDDSA_ED448 =
"http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
/** Signature - Optional RSASSA-PSS */
public static final String ALGO_ID_SIGNATURE_RSA_PSS =
Constants.XML_DSIG_NS_MORE_07_05 + "rsa-pss";

View File

@@ -127,7 +127,7 @@ public class XMLSignatureInputDebugger {
/**
* Constructor XMLSignatureInputDebugger
*
* @param xmlSignatureInput the signatur to pretty print
* @param xmlSignatureInput the signature to pretty print
* @param inclusiveNamespace
*/
public XMLSignatureInputDebugger(

View File

@@ -309,7 +309,7 @@ public final class Transform extends SignatureElementProxy {
/**
* Transforms the input, and generates {@link XMLSignatureInput} as output.
*
* @param input input {@link XMLSignatureInput} which can supplied Octect
* @param input input {@link XMLSignatureInput} which can supplied Octet
* Stream and NodeSet as Input of Transformation
* @param os where to output the result of the last transformation
* @param secureValidation Whether secure validation is enabled

View File

@@ -20,10 +20,16 @@
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
*/
package com.sun.org.apache.xml.internal.security.transforms.implementations;
import java.io.IOException;
import java.io.OutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Security;
import javax.xml.transform.TransformerException;
@@ -33,10 +39,7 @@ import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.transforms.TransformSpi;
import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
import com.sun.org.apache.xml.internal.security.transforms.Transforms;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import com.sun.org.apache.xml.internal.security.utils.XPathAPI;
import com.sun.org.apache.xml.internal.security.utils.XPathFactory;
import com.sun.org.apache.xml.internal.security.utils.*;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -52,8 +55,25 @@ import org.w3c.dom.Node;
*/
public class TransformXPath extends TransformSpi {
private static final com.sun.org.slf4j.internal.Logger LOG =
com.sun.org.slf4j.internal.LoggerFactory.getLogger(TransformXPath.class);
// Whether the here() XPath function is supported.
static final boolean HEREFUNC;
static {
@SuppressWarnings("removal")
String prop =
AccessController.doPrivileged((PrivilegedAction<String>) () ->
Security.getProperty("jdk.xml.dsig.hereFunctionSupported"));
if (prop == null) {
HEREFUNC = true; // default true
} else if (prop.equals("true")) {
HEREFUNC = true;
} else if (prop.equals("false")) {
HEREFUNC = false;
} else {
throw new IllegalArgumentException(
"Invalid jdk.xml.dsig.hereFunctionSupported setting: " + prop);
}
}
/**
* {@inheritDoc}
@@ -112,7 +132,9 @@ public class TransformXPath extends TransformSpi {
}
protected XPathFactory getXPathFactory() {
return XPathFactory.newInstance();
return HEREFUNC
? XPathFactory.newInstance()
: new JDKXPathFactory();
}
/**
@@ -140,20 +162,19 @@ public class TransformXPath extends TransformSpi {
/**
* @see com.sun.org.apache.xml.internal.security.signature.NodeFilter#isNodeInclude(org.w3c.dom.Node)
*/
public int isNodeInclude(Node currentNode) {
public int isNodeInclude(Node currentNode) throws TransformationException {
try {
boolean include = xPathAPI.evaluate(currentNode, xpathnode, str, xpathElement);
if (include) {
return 1;
}
return 0;
} catch (TransformerException e) {
LOG.debug("Error evaluating XPath expression", e);
return 0;
} catch (TransformerException ex) {
throw new TransformationException(ex);
}
}
public int isNodeIncludeDO(Node n, int level) {
public int isNodeIncludeDO(Node n, int level) throws TransformationException {
return isNodeInclude(n);
}

View File

@@ -38,6 +38,7 @@ import com.sun.org.apache.xml.internal.security.transforms.TransformSpi;
import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
import com.sun.org.apache.xml.internal.security.transforms.Transforms;
import com.sun.org.apache.xml.internal.security.transforms.params.XPath2FilterContainer;
import com.sun.org.apache.xml.internal.security.utils.JDKXPathFactory;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import com.sun.org.apache.xml.internal.security.utils.XPathAPI;
import com.sun.org.apache.xml.internal.security.utils.XPathFactory;
@@ -94,7 +95,9 @@ public class TransformXPath2Filter extends TransformSpi {
inputDoc = XMLUtils.getOwnerDocument(input.getNodeSet());
}
XPathFactory xpathFactory = XPathFactory.newInstance();
XPathFactory xpathFactory = TransformXPath.HEREFUNC
? XPathFactory.newInstance()
: new JDKXPathFactory();
for (int i = 0; i < xpathElements.length; i++) {
Element xpathElement = xpathElements[i];

View File

@@ -55,7 +55,7 @@ public final class I18n {
/**
* Method translate
*
* translates a message ID into an internationalized String, see alse
* translates a message ID into an internationalized String, see also
* {@code XMLSecurityException.getExceptionMEssage()}. The strings are
* stored in the {@code ResourceBundle}, which is identified in
* {@code exceptionMessagesResourceBundleBase}

View File

@@ -468,15 +468,15 @@ public class RFC2253Parser {
*/
static String trim(String str) {
String trimed = str.trim();
int i = str.indexOf(trimed) + trimed.length();
String trimmed = str.trim();
int i = str.indexOf(trimmed) + trimmed.length();
if (str.length() > i && trimed.endsWith("\\")
&& !trimed.endsWith("\\\\") && str.charAt(i) == ' ') {
trimed = trimed + " ";
if (str.length() > i && trimmed.endsWith("\\")
&& !trimmed.endsWith("\\\\") && str.charAt(i) == ' ') {
trimmed = trimmed + " ";
}
return trimed;
return trimmed;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@ import java.security.spec.AlgorithmParameterSpec;
/**
* A representation of the XML <code>DigestMethod</code> element as
* defined in the <a href="http://www.w3.org/TR/xmldsig-core/">
* defined in the <a href="https://www.w3.org/TR/xmldsig-core/">
* W3C Recommendation for XML-Signature Syntax and Processing</a>.
* The XML Schema Definition is defined as:
* <pre>
@@ -51,6 +51,12 @@ import java.security.spec.AlgorithmParameterSpec;
* A <code>DigestMethod</code> instance may be created by invoking the
* {@link XMLSignatureFactory#newDigestMethod newDigestMethod} method
* of the {@link XMLSignatureFactory} class.
* <p>
* The digest method algorithm URIs defined in this class are specified
* in the <a href="https://www.w3.org/TR/xmldsig-core/">
* W3C Recommendation for XML-Signature Syntax and Processing</a>
* and <a href="https://www.rfc-editor.org/info/rfc9231">
* RFC 9231: Additional XML Security Uniform Resource Identifiers (URIs)</a>
*
* @author Sean Mullan
* @author JSR 105 Expert Group
@@ -59,8 +65,6 @@ import java.security.spec.AlgorithmParameterSpec;
*/
public interface DigestMethod extends XMLStructure, AlgorithmMethod {
// All methods can be found in RFC 6931.
/**
* The <a href="http://www.w3.org/2000/09/xmldsig#sha1">
* SHA1</a> digest method algorithm URI.

View File

@@ -34,7 +34,7 @@ import java.security.spec.AlgorithmParameterSpec;
/**
* A representation of the XML <code>SignatureMethod</code> element
* as defined in the <a href="http://www.w3.org/TR/xmldsig-core/">
* as defined in the <a href="https://www.w3.org/TR/xmldsig-core/">
* W3C Recommendation for XML-Signature Syntax and Processing</a>.
* The XML Schema Definition is defined as:
* <pre>
@@ -52,6 +52,12 @@ import java.security.spec.AlgorithmParameterSpec;
* A <code>SignatureMethod</code> instance may be created by invoking the
* {@link XMLSignatureFactory#newSignatureMethod newSignatureMethod} method
* of the {@link XMLSignatureFactory} class.
* <p>
* The signature method algorithm URIs defined in this class are specified
* in the <a href="https://www.w3.org/TR/xmldsig-core/">
* W3C Recommendation for XML-Signature Syntax and Processing</a>
* and <a href="https://www.rfc-editor.org/info/rfc9231">
* RFC 9231: Additional XML Security Uniform Resource Identifiers (URIs)</a>
*
* @author Sean Mullan
* @author JSR 105 Expert Group
@@ -60,8 +66,6 @@ import java.security.spec.AlgorithmParameterSpec;
*/
public interface SignatureMethod extends XMLStructure, AlgorithmMethod {
// All methods can be found in RFC 6931.
/**
* The <a href="http://www.w3.org/2000/09/xmldsig#dsa-sha1">DSA-SHA1</a>
* (DSS) signature method algorithm URI.
@@ -255,6 +259,22 @@ public interface SignatureMethod extends XMLStructure, AlgorithmMethod {
*/
String RSA_PSS = "http://www.w3.org/2007/05/xmldsig-more#rsa-pss";
/**
* The <a href="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519">
* ED25519</a> signature method algorithm URI.
*
* @since 21
*/
String ED25519 = "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
/**
* The <a href="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448">
* ED448</a> signature method algorithm URI.
*
* @since 21
*/
String ED448 = "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
/**
* Returns the algorithm-specific input parameters of this
* <code>SignatureMethod</code>.

View File

@@ -49,7 +49,7 @@ abstract class AbstractDOMSignatureMethod extends DOMStructure
implements SignatureMethod {
// denotes the type of signature algorithm
enum Type { DSA, RSA, ECDSA, HMAC }
enum Type { DSA, RSA, ECDSA, EDDSA, HMAC }
/**
* Verifies the passed-in signature with the specified key, using the

View File

@@ -31,6 +31,8 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.xml.crypto.NodeSetData;
import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
import org.w3c.dom.Node;
import com.sun.org.apache.xml.internal.security.signature.NodeFilter;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
@@ -46,11 +48,11 @@ public class ApacheNodeSetData implements ApacheData, NodeSetData<Node> {
public Iterator<Node> iterator() {
// If nodefilters are set, must execute them first to create node-set
if (xi.getNodeFilters() != null && !xi.getNodeFilters().isEmpty()) {
return Collections.unmodifiableSet
(getNodeSet(xi.getNodeFilters())).iterator();
}
try {
if (xi.getNodeFilters() != null && !xi.getNodeFilters().isEmpty()) {
return Collections.unmodifiableSet
(getNodeSet(xi.getNodeFilters())).iterator();
}
return Collections.unmodifiableSet(xi.getNodeSet()).iterator();
} catch (Exception e) {
// should not occur
@@ -63,7 +65,8 @@ public class ApacheNodeSetData implements ApacheData, NodeSetData<Node> {
return xi;
}
private Set<Node> getNodeSet(List<NodeFilter> nodeFilters) {
private Set<Node> getNodeSet(List<NodeFilter> nodeFilters)
throws TransformationException {
if (xi.isNeedsToBeExpanded()) {
XMLUtils.circumventBug2650
(XMLUtils.getOwnerDocument(xi.getSubNode()));

View File

@@ -82,6 +82,12 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
static final String DSA_SHA256 =
"http://www.w3.org/2009/xmldsig11#dsa-sha256";
// see RFC 9231 for these algorithm definitions
static final String ED25519 =
"http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
static final String ED448 =
"http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
// see RFC 6931 for these algorithm definitions
static final String ECDSA_RIPEMD160 =
"http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160";
@@ -220,6 +226,10 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
return new DOMHMACSignatureMethod.SHA512(smElem);
} else if (alg.equals(DOMHMACSignatureMethod.HMAC_RIPEMD160)) {
return new DOMHMACSignatureMethod.RIPEMD160(smElem);
} else if (alg.equals(ED25519)) {
return new EDDSA_ED25519(smElem);
} else if (alg.equals(ED448)) {
return new EDDSA_ED448(smElem);
} else {
throw new MarshalException
("unsupported SignatureMethod algorithm: " + alg);
@@ -542,6 +552,39 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
}
}
abstract static class AbstractEDDSASignatureMethod
extends DOMSignatureMethod {
AbstractEDDSASignatureMethod(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
}
AbstractEDDSASignatureMethod(Element dmElem) throws MarshalException {
super(dmElem);
}
/**
* Returns {@code sig}. No extra formatting is necessary for EDDSA
* See the RFC8032
*/
@Override
byte[] postSignFormat(Key key, byte[] sig) {
return sig;
}
/**
* Returns {@code sig}. No extra formatting is necessary for EDDSA
* See the RFC8032
*/
@Override
byte[] preVerifyFormat(Key key, byte[] sig) {
return sig;
}
}
static final class SHA1withRSA extends AbstractRSASignatureMethod {
SHA1withRSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
@@ -1021,4 +1064,56 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
}
}
static final class EDDSA_ED25519 extends AbstractEDDSASignatureMethod {
EDDSA_ED25519(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
}
EDDSA_ED25519(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return ED25519;
}
@Override
String getJCAAlgorithm() {
return "Ed25519";
}
@Override
Type getAlgorithmType() {
return Type.EDDSA;
}
}
static final class EDDSA_ED448 extends AbstractEDDSASignatureMethod {
EDDSA_ED448(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
}
EDDSA_ED448(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return ED448;
}
@Override
String getJCAAlgorithm() {
return "Ed448";
}
@Override
Type getAlgorithmType() {
return Type.EDDSA;
}
}
}

View File

@@ -302,6 +302,10 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
return new DOMSignatureMethod.SHA512withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_RIPEMD160)) {
return new DOMSignatureMethod.RIPEMD160withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ED25519)) {
return new DOMSignatureMethod.EDDSA_ED25519(params);
} else if (algorithm.equals(DOMSignatureMethod.ED448)) {
return new DOMSignatureMethod.EDDSA_ED448(params);
}else {
throw new NoSuchAlgorithmException("unsupported algorithm");
}

View File

@@ -134,7 +134,7 @@ public final class XMLDSigRI extends Provider {
@SuppressWarnings("removal")
public XMLDSigRI() {
// This is the JDK XMLDSig provider, synced from
// Apache Santuario XML Security for Java, version 2.3.0
// Apache Santuario XML Security for Java, version 3.0.2
super("XMLDSig", VER, INFO);
final Provider p = this;

View File

@@ -1,24 +1,7 @@
## Apache Santuario v2.3.0
### Apache Santuario Notice
<pre>
Apache Santuario - XML Security for Java
Copyright 1999-2021 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
It was originally based on software copyright (c) 2001, Institute for
Data Communications Systems, <http://www.nue.et-inf.uni-siegen.de/>.
The development of this software was partly funded by the European
Commission in the <WebSig> project in the ISIS Programme.
</pre>
## Apache Santuario v3.0.2
### Apache 2.0 License
<pre>
```
Apache License
Version 2.0, January 2004
@@ -222,4 +205,23 @@ 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.
</pre>
```
### Apache Santuario Notice
```
Apache Santuario - XML Security for Java
Copyright 1999-2023 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
It was originally based on software copyright (c) 2001, Institute for
Data Communications Systems, <http://www.nue.et-inf.uni-siegen.de/>.
The development of this software was partly funded by the European
Commission in the <WebSig> project in the ISIS Programme.
This product contains software that is
copyright (c) 2021, Oracle and/or its affiliates.
```

View File

@@ -213,6 +213,7 @@ jdk_security1 = \
jdk_security2 = \
javax/crypto \
javax/xml/crypto \
com/sun/org/apache/xml/internal/security \
com/sun/crypto
jdk_security3 = \
@@ -220,7 +221,6 @@ jdk_security3 = \
-javax/security/auth/kerberos \
com/sun/security \
-com/sun/security/jgss \
com/sun/org/apache/xml/internal/security \
jdk/security \
sun/security \
-sun/security/krb5 \

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import jdk.test.lib.Asserts;
import jdk.test.lib.SecurityTools;
import jdk.test.lib.Utils;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;
import static jdk.test.lib.security.XMLUtils.*;
/**
* @test
* @bug 8305972
* @summary Basic tests using XMLUtils
* @library /test/lib
* @modules java.xml.crypto
*/
public class Basic {
public static void main(String[] args) throws Exception {
var x = "<a><b>c</b>x</a>";
var p = Files.write(Path.of("x.xml"), List.of(x));
var b = Path.of("").toUri().toString();
var d = string2doc(x);
var pass = "changeit".toCharArray();
for (String alg: List.of("DSA", "RSA", "RSASSA-PSS", "EC", "EdDSA", "Ed25519", "Ed448")) {
SecurityTools.keytool(String.format(
"-keystore ks -keyalg %s -storepass changeit -genkeypair -alias %s -dname CN=%s",
alg, alg, alg)).shouldHaveExitValue(0);
var ks = KeyStore.getInstance(new File("ks"), pass);
var c = (X509Certificate) ks.getCertificate(alg);
var pr = (PrivateKey) ks.getKey(alg, pass);
var pu = c.getPublicKey();
var s0 = signer(pr); // No KeyInfo
var s1 = signer(pr, c); // KeyInfo is X509Data
var s2 = signer(ks, alg, pass); // KeyInfo is KeyName
var v1 = validator(); // knows nothing
var v2 = validator(ks); // knows KeyName
Utils.runAndCheckException(() -> v1.validate(s0.sign(d)), IllegalArgumentException.class); // need PublicKey
s0.sign(string2doc(x));
Asserts.assertTrue(v1.validate(s0.sign(d), pu)); // need PublicKey
Asserts.assertTrue(v1.validate(s1.sign(d))); // can read KeyInfo
Asserts.assertTrue(v2.validate(s2.sign(d))); // can read KeyInfo
Asserts.assertTrue(v2.secureValidation(false).validate(s2.sign(p.toUri()))); // can read KeyInfo
Asserts.assertTrue(v2.secureValidation(false).baseURI(b).validate(
s2.sign(p.toAbsolutePath().getParent().toUri(), p.getFileName().toUri()))); // can read KeyInfo
Asserts.assertTrue(v1.validate(s0.sign("text"), pu)); // plain text
Asserts.assertTrue(v1.validate(s0.sign("binary".getBytes()), pu)); // raw data
Asserts.assertTrue(v1.validate(s0.signEnveloping(d, "x", "#x"), pu));
Asserts.assertTrue(v1.validate(s0.signEnveloping(d, "x", "#xpointer(id('x'))"), pu));
// No KeyValue defined for RSASSA-PSS or EdDSA yet
if (!alg.startsWith("Ed") && !alg.equals("RSASSA-PSS")) {
var ss = signer(pr, pu); // KeyInfo is PublicKey
Asserts.assertTrue(v1.validate(ss.sign(d))); // can read KeyInfo
Asserts.assertTrue(v1.validate(ss.sign("text"))); // plain text
Asserts.assertTrue(v1.validate(ss.sign("binary".getBytes()))); // raw data
Asserts.assertTrue(v1.validate(ss.signEnveloping(d, "x", "#x")));
Asserts.assertTrue(v1.validate(ss.signEnveloping(d, "x", "#xpointer(id('x'))")));
}
}
}
}

View File

@@ -24,7 +24,7 @@
/**
* @test
* @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349 8046949
* 8046724 8079693 8177334 8205507 8210736 8217878 8241306
* 8046724 8079693 8177334 8205507 8210736 8217878 8241306 8305972
* @summary Basic unit tests for generating XML Signatures with JSR 105
* @modules java.base/sun.security.util
* java.base/sun.security.x509
@@ -56,18 +56,8 @@ import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.spec.KeySpec;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.ECField;
import java.security.spec.ECFieldFp;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.cert.X509Certificate;
import java.security.spec.*;
import java.util.*;
import java.util.stream.Stream;
import javax.crypto.KeyGenerator;
@@ -110,12 +100,14 @@ public class GenerationTests {
rsaSha1, rsaSha224, rsaSha256, rsaSha384, rsaSha512,
ecdsaSha1, ecdsaSha224, ecdsaSha256, ecdsaSha384, ecdsaSha512,
hmacSha1, hmacSha224, hmacSha256, hmacSha384, hmacSha512,
rsaSha1mgf1, rsaSha224mgf1, rsaSha256mgf1, rsaSha384mgf1, rsaSha512mgf1, rsaShaPSS;
rsaSha1mgf1, rsaSha224mgf1, rsaSha256mgf1, rsaSha384mgf1, rsaSha512mgf1,
rsaShaPSS, ed25519, ed448;
private static DigestMethod sha1, sha224, sha256, sha384, sha512,
sha3_224, sha3_256, sha3_384, sha3_512;
private static KeyInfo dsa1024, dsa2048, rsa, rsa1024, rsa2048,
p256ki, p384ki, p521ki;
p256ki, p384ki, p521ki, ed25519ki, ed448ki;
private static KeySelector kvks = new KeySelectors.KeyValueKeySelector();
private static KeySelector x5ks = new KeySelectors.RawX509KeySelector();
private static KeySelector sks;
private static Key signingKey;
private static PublicKey validatingKey;
@@ -217,7 +209,8 @@ public class GenerationTests {
SignatureMethod.ECDSA_SHA256,
SignatureMethod.HMAC_SHA256,
SignatureMethod.SHA256_RSA_MGF1,
SignatureMethod.RSA_PSS);
SignatureMethod.RSA_PSS,
SignatureMethod.ED25519);
private static final String[] allSignatureMethods
= Stream.of(SignatureMethod.class.getDeclaredFields())
@@ -251,7 +244,7 @@ public class GenerationTests {
// As of JDK 17, the number of defined algorithms are...
static {
if (allSignatureMethods.length != 23
if (allSignatureMethods.length != 25
|| allDigestMethods.length != 9) {
System.out.println(Arrays.toString(allSignatureMethods));
System.out.println(Arrays.toString(allDigestMethods));
@@ -312,6 +305,8 @@ public class GenerationTests {
test_create_signature_enveloping_p256_sha512();
test_create_signature_enveloping_p384_sha1();
test_create_signature_enveloping_p521_sha1();
test_create_signature_enveloping_ed25519();
test_create_signature_enveloping_ed448();
test_create_signature_external_b64_dsa();
test_create_signature_external_dsa();
test_create_signature_keyname();
@@ -359,8 +354,10 @@ public class GenerationTests {
Arrays.stream(xml_transforms).forEach(t ->
Arrays.stream(KeyInfoType.values()).forEach(k -> {
if (isMajor(s, d)) {
test_create_detached_signature(c, s, d, t, k,
Content.Xml, server.getPort(), false, null);
if (!s.contains("#eddsa") || k != KeyInfoType.KeyValue) {
test_create_detached_signature(c, s, d, t, k,
Content.Xml, server.getPort(), false, null);
}
}
})))));
@@ -370,8 +367,10 @@ public class GenerationTests {
Arrays.stream(allDigestMethods).forEach(d ->
Arrays.stream(KeyInfoType.values()).forEach(k -> {
if (isMajor(s, d)) {
test_create_detached_signature(c, s, d, null, k,
Content.Text, server.getPort(), false, null);
if (!s.contains("#eddsa") || k != KeyInfoType.KeyValue) {
test_create_detached_signature(c, s, d, null, k,
Content.Text, server.getPort(), false, null);
}
}
}))));
@@ -382,9 +381,11 @@ public class GenerationTests {
Arrays.stream(non_xml_transforms).forEach(t ->
Arrays.stream(KeyInfoType.values()).forEach(k -> {
if (isMajor(s, d)) {
test_create_detached_signature(c, s, d, t, k,
Content.Base64, server.getPort(),
false, null);
if (!s.contains("#eddsa") || k != KeyInfoType.KeyValue) {
test_create_detached_signature(c, s, d, t, k,
Content.Base64, server.getPort(),
false, null);
}
}
})))));
@@ -525,6 +526,11 @@ public class GenerationTests {
p521ki = kifac.newKeyInfo(Collections.singletonList
(kifac.newKeyValue(getECPublicKey("P521"))));
ed25519ki = kifac.newKeyInfo(Collections.singletonList
(kifac.newX509Data(List.of(getEd25519Certificate()))));
ed448ki = kifac.newKeyInfo(Collections.singletonList
(kifac.newX509Data(List.of(getEd448Certificate()))));
rsaSha1 = fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
rsaSha224 = fac.newSignatureMethod(SignatureMethod.RSA_SHA224, null);
rsaSha256 = fac.newSignatureMethod(SignatureMethod.RSA_SHA256, null);
@@ -544,6 +550,9 @@ public class GenerationTests {
ecdsaSha384 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA384, null);
ecdsaSha512 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA512, null);
ed25519 = fac.newSignatureMethod(SignatureMethod.ED25519, null);
ed448 = fac.newSignatureMethod(SignatureMethod.ED448, null);
hmacSha1 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA1, null);
hmacSha224 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA224, null);
hmacSha256 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA256, null);
@@ -855,6 +864,20 @@ public class GenerationTests {
System.out.println();
}
static void test_create_signature_enveloping_ed25519() throws Exception {
System.out.println("* Generating signature-enveloping-ed25519.xml");
test_create_signature_enveloping(sha1, ed25519, ed25519ki,
getEd25519PrivateKey(), x5ks, false, true);
System.out.println();
}
static void test_create_signature_enveloping_ed448() throws Exception {
System.out.println("* Generating signature-enveloping-ed448.xml");
test_create_signature_enveloping(sha1, ed448, ed448ki,
getEd448PrivateKey(), x5ks, false, true);
System.out.println();
}
static void test_create_signature_external_b64_dsa() throws Exception {
System.out.println("* Generating signature-external-b64-dsa.xml");
test_create_signature_external(dsaSha1, dsa1024, signingKey, kvks, true);
@@ -1957,6 +1980,8 @@ public class GenerationTests {
} else if (sm.contains("#ecdsa-")) {
kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(256);
} else if (sm.contains("#eddsa-")) {
kpg = KeyPairGenerator.getInstance(sm.substring(sm.lastIndexOf('-') + 1));
} else {
throw new RuntimeException("Unsupported signature algorithm");
}
@@ -2085,6 +2110,20 @@ public class GenerationTests {
1
);
private static final String ED25519_CERT =
"3081d730818aa003020102020822bc4997b1893265300506032b657030123110300e0603550403130745643235353139301e170d3233303431333033303732365a170d3433303430383033303" +
"732365a30123110300e0603550403130745643235353139302a300506032b657003210012ecd7383ac90c30035dc531285bdb897faafddfc6969271c2ebd9a82b6078e5300506032b65700341" +
"00a3cb7c03bbb3e9fa92eaf3f9a6f2608460d472c6a6ce3bebf0f57f45612e87ebdc6aa6d7527ae9e86c8e10bcccf98963f9b082c0bb44adb240c5fce9bb68b301";
private static final String ED25519_KEY =
"b59e57e352fa03b3a643946ae60b7f1e276f9ab41f25accaa63b660ba36168b2";
private static final String ED448_CERT =
"3082011f3081a0a003020102020900ceaefd75473d52b2300506032b65713010310e300c060355040313054564343438301e170d3233303431333033303735345a170d3433303430383033303" +
"735345a3010310e300c0603550403130545643434383043300506032b6571033a00d605be958f21faf6a1181fa96ebe8580cca3cae9b48dfad5145ee999d9df4ef77c355d33ae8b21e9a3541f" +
"b985ae366b9678db1a3fd1fd5c00300506032b65710373000b4dc8de20b261f5ca7cf41777725a2ec6cd107d6b75cd6ad02c00af8096ecf97c7445596aabd70381ce087d2b3b280ca4181566b" +
"9230fd6801e22e53f1514989bc5b06cfb5f7cac222ea9a37a0771a3f7cfcbfd1ba9546bbe333d37ee81c3a53d86247d377225114e1e81123f947a391800";
private static final String ED448_KEY =
"50b72f081f7f2f3383c4b03975cf49a76ba8b17dec51eaea3cd267b6989b81786e8dd8af4df305eaad60bdd24345b8490548c371d62e926f80";
private static ECParameterSpec initECParams(
String sfield, String a, String b, String gx, String gy,
String n, int h) {
@@ -2158,6 +2197,16 @@ public class GenerationTests {
return kf.generatePublic(kspec);
}
private static X509Certificate getEd25519Certificate() throws Exception {
return (X509Certificate) CertificateFactory.getInstance("X.509")
.generateCertificate(new ByteArrayInputStream(HexFormat.of().parseHex(ED25519_CERT)));
}
private static X509Certificate getEd448Certificate() throws Exception {
return (X509Certificate) CertificateFactory.getInstance("X.509")
.generateCertificate(new ByteArrayInputStream(HexFormat.of().parseHex(ED448_CERT)));
}
private static PrivateKey getPrivateKey(String algo, int keysize)
throws Exception {
KeyFactory kf = KeyFactory.getInstance(algo);
@@ -2211,6 +2260,16 @@ public class GenerationTests {
return kf.generatePrivate(kspec);
}
private static PrivateKey getEd25519PrivateKey() throws Exception {
return KeyFactory.getInstance("Ed25519").generatePrivate(new EdECPrivateKeySpec(
NamedParameterSpec.ED25519, HexFormat.of().parseHex(ED25519_KEY)));
}
private static PrivateKey getEd448PrivateKey() throws Exception {
return KeyFactory.getInstance("Ed448").generatePrivate(new EdECPrivateKeySpec(
NamedParameterSpec.ED448, HexFormat.of().parseHex(ED448_KEY)));
}
private static SecretKey getSecretKey(final byte[] secret) {
return new SecretKey() {
public String getFormat() { return "RAW"; }

View File

@@ -0,0 +1,240 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8305972
* @summary Demonstrate here() support for validating XML Signatures
* @modules java.base/sun.security.util
* java.base/sun.security.x509
* java.xml.crypto/org.jcp.xml.dsig.internal.dom
* @library /test/lib
* @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
* X509KeySelector.java ValidationTests.java
* @run main/othervm HereFunction default true
* @run main/othervm HereFunction true true
* @run main/othervm HereFunction false false
*/
import java.io.File;
import java.io.FileInputStream;
import java.security.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.crypto.Data;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.OctetStreamData;
import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.URIReference;
import javax.xml.crypto.URIReferenceException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec;
import javax.xml.parsers.DocumentBuilderFactory;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
import jdk.test.lib.security.SecurityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class HereFunction {
private final static String DIR = System.getProperty("test.src", ".");
private final static String DATA_DIR =
DIR + System.getProperty("file.separator") + "data";
private final static String KEYSTORE_VERIFY =
DATA_DIR + System.getProperty("file.separator") + "certs" +
System.getProperty("file.separator") + "xmldsig.jks";
private final static String KEYSTORE_SIGN =
DATA_DIR + System.getProperty("file.separator") + "certs" +
System.getProperty("file.separator") + "test.jks";
private final static String STYLESHEET =
"http://www.w3.org/TR/xml-stylesheet";
private final static String STYLESHEET_B64 =
"http://www.w3.org/Signature/2002/04/xml-stylesheet.b64";
private final static char[] PASS = "changeit".toCharArray();
public static void main(String args[]) throws Throwable {
if (!args[0].equals("default")) {
Security.setProperty("jdk.xml.dsig.hereFunctionSupported", args[0]);
}
// Re-enable sha1 algs
SecurityUtils.removeAlgsFromDSigPolicy("sha1");
boolean expected = Boolean.parseBoolean(args[1]);
sign(expected);
// Validating an old signature signed by JDK < 21
validate(expected);
}
static void validate(boolean expected) throws Exception {
SignatureValidator validator = new SignatureValidator(new File(DATA_DIR));
KeyStore keystore = KeyStore.getInstance(new File(KEYSTORE_VERIFY), PASS);
KeySelector ks = new X509KeySelector(keystore, false);
if (expected) {
Asserts.assertTrue(validator.validate(
"signature.xml", ks, new HttpURIDereferencer(), false));
} else {
Utils.runAndCheckException(() -> validator.validate(
"signature.xml", ks, new HttpURIDereferencer(), false),
XMLSignatureException.class);
}
}
static void sign(boolean expected) throws Exception {
XMLSignatureFactory fac = XMLSignatureFactory.getInstance();
DigestMethod sha1 = fac.newDigestMethod(DigestMethod.SHA1, null);
CanonicalizationMethod withoutComments = fac.newCanonicalizationMethod
(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec)null);
SignatureMethod dsaSha1 = fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null);
KeyInfoFactory kifac = fac.getKeyInfoFactory();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
String ENVELOPE =
DATA_DIR + System.getProperty("file.separator") + "envelope.xml";
var ks = KeyStore.getInstance(new File(KEYSTORE_SIGN), PASS);
var signingKey = ks.getKey("user", PASS);
var signingCert = ks.getCertificate("user");
// create references
List<Reference> refs = new ArrayList<>();
// Reference 1
refs.add(fac.newReference(STYLESHEET, sha1));
// Reference 2
String expr = "\n"
+ " ancestor-or-self::dsig:SignedInfo " + "\n"
+ " and " + "\n"
+ " count(ancestor-or-self::dsig:Reference | " + "\n"
+ " here()/ancestor::dsig:Reference[1]) > " + "\n"
+ " count(ancestor-or-self::dsig:Reference) " + "\n"
+ " or " + "\n"
+ " count(ancestor-or-self::node() | " + "\n"
+ " id('notaries')) = " + "\n"
+ " count(ancestor-or-self::node()) " + "\n";
XPathFilterParameterSpec xfp = new XPathFilterParameterSpec(expr,
Collections.singletonMap("dsig", XMLSignature.XMLNS));
refs.add(fac.newReference("", sha1, Collections.singletonList
(fac.newTransform(Transform.XPATH, xfp)),
XMLObject.TYPE, null));
// create SignedInfo
SignedInfo si = fac.newSignedInfo(withoutComments, dsaSha1, refs);
// create keyinfo
KeyInfo ki = kifac.newKeyInfo(List.of(
kifac.newX509Data(List.of(signingCert))), null);
// create XMLSignature
XMLSignature sig = fac.newXMLSignature(si, ki, null, "signature", null);
dbf.setValidating(false);
Document envDoc = dbf.newDocumentBuilder()
.parse(new FileInputStream(ENVELOPE));
Element ys = (Element)
envDoc.getElementsByTagName("YoursSincerely").item(0);
DOMSignContext dsc = new DOMSignContext(signingKey, ys);
dsc.setURIDereferencer(new HttpURIDereferencer());
if (expected) {
sig.sign(dsc);
} else {
Utils.runAndCheckException(
() -> sig.sign(dsc), XMLSignatureException.class);
return; // Signing fails, no need to validate
}
// StringWriter sw = new StringWriter();
// dumpDocument(envDoc, sw);
NodeList nl =
envDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
throw new Exception("Couldn't find signature Element");
}
Element sigElement = (Element) nl.item(0);
DOMValidateContext dvc = new DOMValidateContext
(new X509KeySelector(ks), sigElement);
dvc.setURIDereferencer(new HttpURIDereferencer());
File f = new File(
System.getProperty("dir.test.vector.baltimore") +
System.getProperty("file.separator") +
"merlin-xmldsig-twenty-three" +
System.getProperty("file.separator"));
dvc.setBaseURI(f.toURI().toString());
XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
if (sig.equals(sig2) == false) {
throw new Exception
("Unmarshalled signature is not equal to generated signature");
}
if (sig2.validate(dvc) == false) {
throw new Exception("Validation of generated signature failed");
}
}
/**
* This URIDereferencer returns locally cached copies of http content to
* avoid test failures due to network glitches, etc.
*/
private static class HttpURIDereferencer implements URIDereferencer {
private final URIDereferencer defaultUd;
HttpURIDereferencer() {
defaultUd = XMLSignatureFactory.getInstance().getURIDereferencer();
}
public Data dereference(final URIReference ref, XMLCryptoContext ctx)
throws URIReferenceException {
String uri = ref.getURI();
if (uri.equals(STYLESHEET) || uri.equals(STYLESHEET_B64)) {
try {
FileInputStream fis = new FileInputStream(new File
(DATA_DIR, uri.substring(uri.lastIndexOf('/'))));
return new OctetStreamData(fis,ref.getURI(),ref.getType());
} catch (Exception e) { throw new URIReferenceException(e); }
}
// fallback on builtin deref
return defaultUd.dereference(ref, ctx);
}
}
}

View File

@@ -29,6 +29,7 @@
* @library /test/lib
* @modules java.base/sun.security.tools.keytool
* java.base/sun.security.x509
* @run main/othervm SecureValidation
*/
import jdk.test.lib.Asserts;
import jdk.test.lib.security.XMLUtils;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
package jdk.test.lib.security;
import jdk.test.lib.Asserts;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -49,15 +48,14 @@ import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.*;
import java.security.cert.X509Certificate;
import java.security.interfaces.EdECPrivateKey;
import java.security.interfaces.RSAKey;
import java.security.spec.NamedParameterSpec;
import java.security.spec.PSSParameterSpec;
import java.util.*;
@@ -68,37 +66,6 @@ public class XMLUtils {
private static final XMLSignatureFactory FAC =
XMLSignatureFactory.getInstance("DOM");
//////////// MAIN as TEST ////////////
public static void main(String[] args) throws Exception {
var x = "<a><b>c</b>x</a>";
var p = Files.write(Path.of("x.xml"), List.of(x));
var b = Path.of("").toUri().toString();
var d = string2doc(x);
// keytool -keystore ks -keyalg ec -storepass changeit -genkeypair -alias a -dname CN=a
var pass = "changeit".toCharArray();
var ks = KeyStore.getInstance(new File("ks"), pass);
var c = (X509Certificate) ks.getCertificate("a");
var pr = (PrivateKey) ks.getKey("a", pass);
var pu = c.getPublicKey();
var s0 = signer(pr); // No KeyInfo
var s1 = signer(pr, pu); // KeyInfo is PublicKey
var s2 = signer(pr, c); // KeyInfo is X509Data
var s3 = signer(ks, "a", pass); // KeyInfo is KeyName
var v1 = validator(); // knows nothing
var v2 = validator(ks); // knows KeyName
Asserts.assertTrue(v1.validate(s0.sign(d), pu)); // need PublicKey
Asserts.assertTrue(v1.validate(s1.sign(d))); // can read KeyInfo
Asserts.assertTrue(v1.validate(s2.sign(d))); // can read KeyInfo
Asserts.assertTrue(v2.validate(s3.sign(d))); // can read KeyInfo
Asserts.assertTrue(v2.secureValidation(false).validate(s3.sign(p.toUri()))); // can read KeyInfo
Asserts.assertTrue(v2.secureValidation(false).baseURI(b).validate(
s3.sign(p.toAbsolutePath().getParent().toUri(), p.getFileName().toUri()))); // can read KeyInfo
Asserts.assertTrue(v1.validate(s1.sign("text"))); // plain text
Asserts.assertTrue(v1.validate(s1.sign("binary".getBytes()))); // raw data
Asserts.assertTrue(v1.validate(s1.signEnveloping(d, "x", "#x")));
Asserts.assertTrue(v1.validate(s1.signEnveloping(d, "x", "#xpointer(id('x'))")));
}
//////////// CONVERT ////////////
// Converts a Document object to string
@@ -220,38 +187,20 @@ public class XMLUtils {
public static class Signer {
PrivateKey privateKey; // signer key, never null
final PrivateKey privateKey; // signer key, never null
X509Certificate cert; // certificate, optional
PublicKey publicKey; // public key, optional
String keyName; // alias, optional
SignatureMethod sm; // default determined by privateKey
DigestMethod dm; // default SHA-256
CanonicalizationMethod cm; // default EXCLUSIVE
Transform tr; // default ENVELOPED
String sm = null; // default determined by privateKey
SignatureMethodParameterSpec smSpec = null;
String dm = DigestMethod.SHA256;
String cm = CanonicalizationMethod.EXCLUSIVE;
String tr = Transform.ENVELOPED;
public Signer(PrivateKey privateKey) throws Exception {
this.privateKey = privateKey;
dm(DigestMethod.SHA256);
tr(Transform.ENVELOPED);
cm(CanonicalizationMethod.EXCLUSIVE);
String alg = privateKey.getAlgorithm();
if (alg.equals("RSASSA-PSS")) {
PSSParameterSpec pspec
= (PSSParameterSpec) ((RSAKey) privateKey).getParams();
if (pspec != null) {
sm(SignatureMethod.RSA_PSS, new RSAPSSParameterSpec(pspec));
} else {
sm(SignatureMethod.RSA_PSS);
}
} else {
sm(switch (privateKey.getAlgorithm()) {
case "RSA" -> SignatureMethod.RSA_SHA256;
case "DSA" -> SignatureMethod.DSA_SHA256;
case "EC" -> SignatureMethod.ECDSA_SHA256;
default -> throw new InvalidKeyException();
});
}
public Signer(PrivateKey privateKey) {
this.privateKey = Objects.requireNonNull(privateKey);
}
// Change KeyInfo source
@@ -273,47 +222,29 @@ public class XMLUtils {
// Change various methods
public Signer tr(String transform) throws Exception {
TransformParameterSpec params = null;
switch (transform) {
case Transform.XPATH:
params = new XPathFilterParameterSpec("//.");
break;
case Transform.XPATH2:
params = new XPathFilter2ParameterSpec(
Collections.singletonList(new XPathType("//.",
XPathType.Filter.INTERSECT)));
break;
}
tr = FAC.newTransform(transform, params);
public Signer tr(String transform) {
tr = Objects.requireNonNull(transform);
return this;
}
public Signer dm(String method) {
dm = Objects.requireNonNull(method);
return this;
}
public Signer cm(String method) {
cm = Objects.requireNonNull(method);
return this;
}
public Signer sm(String method, SignatureMethodParameterSpec spec) {
sm = method;
smSpec = spec;
return this;
}
public Signer sm(String method) throws Exception {
sm = FAC.newSignatureMethod(method, null);
return this;
}
public Signer dm(String method) throws Exception {
dm = FAC.newDigestMethod(method, null);
return this;
}
public Signer cm(String method) throws Exception {
cm = FAC.newCanonicalizationMethod(method, (C14NMethodParameterSpec) null);
return this;
}
public Signer sm(String method, SignatureMethodParameterSpec spec)
throws Exception {
sm = FAC.newSignatureMethod(method, spec);
return this;
}
public Signer dm(String method, DigestMethodParameterSpec spec)
throws Exception {
dm = FAC.newDigestMethod(method, spec);
return this;
return sm(method, null);
}
// Signs different sources
@@ -353,7 +284,7 @@ public class XMLUtils {
Document newDocument = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
FAC.newXMLSignature(
buildSignedInfo(FAC.newReference(ref, dm)),
buildSignedInfo(FAC.newReference(ref, FAC.newDigestMethod(dm, null))),
buildKeyInfo(),
List.of(FAC.newXMLObject(List.of(new DOMStructure(document.getDocumentElement())),
id, null, null)),
@@ -368,7 +299,7 @@ public class XMLUtils {
Document newDocument = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
FAC.newXMLSignature(
buildSignedInfo(FAC.newReference("#object", dm, List.of
buildSignedInfo(FAC.newReference("#object", FAC.newDigestMethod(dm, null), List.of
(FAC.newTransform(Transform.BASE64,
(TransformParameterSpec) null)), null, null)),
buildKeyInfo(),
@@ -386,9 +317,11 @@ public class XMLUtils {
Document newDocument = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
FAC.newXMLSignature(
buildSignedInfo(FAC.newReference("#object", dm)),
buildSignedInfo(
FAC.newReference("#object", FAC.newDigestMethod(dm, null))),
buildKeyInfo(),
List.of(FAC.newXMLObject(List.of(new DOMStructure(newDocument.createTextNode(str))),
List.of(FAC.newXMLObject(
List.of(new DOMStructure(newDocument.createTextNode(str))),
"object", null, null)),
null,
null)
@@ -397,22 +330,61 @@ public class XMLUtils {
}
// Builds a SignedInfo for a string reference
private SignedInfo buildSignedInfo(String ref) {
return FAC.newSignedInfo(
cm,
sm,
List.of(FAC.newReference(
private SignedInfo buildSignedInfo(String ref) throws Exception {
return buildSignedInfo(FAC.newReference(
ref,
dm,
List.of(tr),
null, null)));
FAC.newDigestMethod(dm, null),
List.of(FAC.newTransform(tr, switch (tr) {
case Transform.XPATH ->
new XPathFilterParameterSpec("//.");
case Transform.XPATH2 -> new XPathFilter2ParameterSpec(
Collections.singletonList(new XPathType("//.",
XPathType.Filter.INTERSECT)));
default -> null;
})),
null, null));
}
// Builds a SignedInfo for a Reference
private SignedInfo buildSignedInfo(Reference ref) {
private SignedInfo buildSignedInfo(Reference ref) throws Exception {
SignatureMethod signatureMethod;
if (sm == null) {
String alg = privateKey.getAlgorithm().toUpperCase(Locale.ROOT);
if (alg.equals("RSASSA-PSS")) {
PSSParameterSpec pspec
= (PSSParameterSpec) ((RSAKey) privateKey).getParams();
if (pspec != null) {
signatureMethod = FAC.newSignatureMethod(
SignatureMethod.RSA_PSS, new RSAPSSParameterSpec(pspec));
} else {
signatureMethod = FAC.newSignatureMethod(SignatureMethod.RSA_PSS, null);
}
} else {
signatureMethod = FAC.newSignatureMethod(switch (alg) {
case "RSA" -> SignatureMethod.RSA_SHA256;
case "DSA" -> SignatureMethod.DSA_SHA256;
case "EC" -> SignatureMethod.ECDSA_SHA256;
case "ED25519" -> SignatureMethod.ED25519;
case "ED448" -> SignatureMethod.ED448;
case "EDDSA" -> {
if (privateKey instanceof EdECPrivateKey edsk) {
yield edsk.getParams().getName()
.equals(NamedParameterSpec.ED25519.getName())
? SignatureMethod.ED25519
: SignatureMethod.ED448;
} else {
throw new InvalidKeyException();
}
}
default -> throw new InvalidKeyException();
}, null);
}
} else {
signatureMethod = FAC.newSignatureMethod(sm, smSpec);
}
return FAC.newSignedInfo(
cm,
sm,
FAC.newCanonicalizationMethod(cm, (C14NMethodParameterSpec) null),
signatureMethod,
List.of(ref));
}
@@ -518,7 +490,9 @@ public class XMLUtils {
AlgorithmMethod method,
XMLCryptoContext context)
throws KeySelectorException {
Objects.requireNonNull(keyInfo, "Null KeyInfo object!");
if (keyInfo == null) {
throw new IllegalArgumentException("Null KeyInfo object!");
}
for (XMLStructure xmlStructure : keyInfo.getContent()) {
PublicKey pk;