mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
8305972: Update XML Security for Java to 3.0.2
Reviewed-by: mullan
(cherry picked from commit f0aebc8141)
This commit is contained in:
committed by
Vitaly Provodin
parent
a5213b8796
commit
aa4a00e69c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.w3c.dom.Node;
|
||||
* Handles {@code <ds:Object>} 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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
```
|
||||
|
||||
@@ -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 \
|
||||
|
||||
93
test/jdk/javax/xml/crypto/dsig/Basic.java
Normal file
93
test/jdk/javax/xml/crypto/dsig/Basic.java
Normal 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'))")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"; }
|
||||
|
||||
240
test/jdk/javax/xml/crypto/dsig/HereFunction.java
Normal file
240
test/jdk/javax/xml/crypto/dsig/HereFunction.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user