Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ abstract class AbstractDOMSignatureMethod extends DOMStructure
implements SignatureMethod {

// denotes the type of signature algorithm
enum Type { DSA, RSA, ECDSA, EDDSA, HMAC }
enum Type { DSA, RSA, ECDSA, EDDSA, MLDSA, HMAC }

/**
* Verifies the passed-in signature with the specified key, using the
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;

import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* DOM-based implementation of XMLSignature.
Expand Down Expand Up @@ -278,6 +280,8 @@ public boolean validate(XMLValidateContext vc)
return validationStatus;
}

checkForUnsupportedSignatureContext(localSigElem);

// validate the signature
boolean sigValidity = sv.validate(vc);
if (!sigValidity) {
Expand Down Expand Up @@ -339,6 +343,30 @@ public boolean validate(XMLValidateContext vc)
return validationStatus;
}

/**
* Rejects a signature that carries an ML-DSA {@code SignatureContext} element
* (draft-eastlake-rfc9231bis-xmlsec-uris-09, section 3.3.15). The
* {@code java.security.Signature} API offers no way to pass a signature context
* to ML-DSA (see the Non-Goals of JEP 497), so such a signature can be neither
* created nor verified correctly here; bail out rather than silently ignoring
* the context.
*/
private static void checkForUnsupportedSignatureContext(Element sigElem)
throws XMLSignatureException
{
if (sigElem == null) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also return if the algorithm is not ML-DSA.

return;
}
NodeList contexts = sigElem.getElementsByTagNameNS(
Constants.XML_DSIG_NS_MORE_26_08, Constants._TAG_SIGNATURECONTEXT);
if (contexts.getLength() > 0) {
throw new XMLSignatureException("The ML-DSA SignatureContext element ("
+ Constants.XML_DSIG_NS_MORE_26_08 + Constants._TAG_SIGNATURECONTEXT
+ ") is not supported: the java.security.Signature API cannot pass a "
+ "signature context to ML-DSA (JEP 497)");
}
}

@Override
public void sign(XMLSignContext signContext)
throws MarshalException, XMLSignatureException
Expand All @@ -350,6 +378,8 @@ public void sign(XMLSignContext signContext)
marshal(context.getParent(), context.getNextSibling(),
DOMUtils.getSignaturePrefix(context), context);

checkForUnsupportedSignatureContext(sigElem);

// generate references and signature value
List<Reference> allReferences = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,44 +281,11 @@ public SignatureMethod newSignatureMethod(String algorithm,
if (algorithm == null) {
throw new NullPointerException();
}
if (algorithm.equals(SignatureMethod.RSA_SHA1)) {
return new DOMSignatureMethod.SHA1withRSA(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA224)) {
return new DOMSignatureMethod.SHA224withRSA(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA256)) {
return new DOMSignatureMethod.SHA256withRSA(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA384)) {
return new DOMSignatureMethod.SHA384withRSA(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512)) {
return new DOMSignatureMethod.SHA512withRSA(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160)) {
return new DOMSignatureMethod.RIPEMD160withRSA(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA1_MGF1)) {
return new DOMSignatureMethod.SHA1withRSAandMGF1(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA224_MGF1)) {
return new DOMSignatureMethod.SHA224withRSAandMGF1(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA256_MGF1)) {
return new DOMSignatureMethod.SHA256withRSAandMGF1(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA384_MGF1)) {
return new DOMSignatureMethod.SHA384withRSAandMGF1(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512_MGF1)) {
return new DOMSignatureMethod.SHA512withRSAandMGF1(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA3_224_MGF1)) {
return new DOMSignatureMethod.SHA3_224withRSAandMGF1(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA3_256_MGF1)) {
return new DOMSignatureMethod.SHA3_256withRSAandMGF1(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA3_384_MGF1)) {
return new DOMSignatureMethod.SHA3_384withRSAandMGF1(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA3_512_MGF1)) {
return new DOMSignatureMethod.SHA3_512withRSAandMGF1(params);
} else if (algorithm.equals(DOMRSAPSSSignatureMethod.RSA_PSS)) {
// A few algorithms take caller-supplied parameters that don't fit the
// shared (URI -> JCA algorithm name) registry below, so they are
// constructed directly here rather than looked up.
if (algorithm.equals(DOMRSAPSSSignatureMethod.RSA_PSS)) {
return new DOMRSAPSSSignatureMethod.RSAPSS(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160_MGF1)) {
return new DOMSignatureMethod.RIPEMD160withRSAandMGF1(params);
} else if (algorithm.equals(SignatureMethod.DSA_SHA1)) {
return new DOMSignatureMethod.SHA1withDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.DSA_SHA256)) {
return new DOMSignatureMethod.SHA256withDSA(params);
} else if (algorithm.equals(SignatureMethod.HMAC_SHA1)) {
return new DOMHMACSignatureMethod.SHA1(params);
} else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA224)) {
Expand All @@ -331,33 +298,12 @@ public SignatureMethod newSignatureMethod(String algorithm,
return new DOMHMACSignatureMethod.SHA512(params);
} else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_RIPEMD160)) {
return new DOMHMACSignatureMethod.RIPEMD160(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA1)) {
return new DOMSignatureMethod.SHA1withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA224)) {
return new DOMSignatureMethod.SHA224withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA256)) {
return new DOMSignatureMethod.SHA256withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA384)) {
return new DOMSignatureMethod.SHA384withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA512)) {
return new DOMSignatureMethod.SHA512withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA3_224)) {
return new DOMSignatureMethod.SHA3_224withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA3_256)) {
return new DOMSignatureMethod.SHA3_256withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA3_384)) {
return new DOMSignatureMethod.SHA3_384withECDSA(params);
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA3_512)) {
return new DOMSignatureMethod.SHA3_512withECDSA(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 {
}
DOMSignatureMethod.AlgEntry entry = DOMSignatureMethod.lookup(algorithm);
if (entry == null) {
throw new NoSuchAlgorithmException("unsupported algorithm");
}
return entry.paramsConstructor.newInstance(params);
}

@Override
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/apache/xml/security/algorithms/JCEMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,18 @@ public static void registerDefaultAlgorithms() {
XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448,
new Algorithm("Ed448", "Ed448", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_MLDSA_44,
new Algorithm("ML-DSA-44", "ML-DSA-44", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_MLDSA_65,
new Algorithm("ML-DSA-65", "ML-DSA-65", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_SIGNATURE_MLDSA_87,
new Algorithm("ML-DSA-87", "ML-DSA-87", "Signature")
);
algorithmsMap.put(
XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5,
new Algorithm("", "HmacMD5", "Mac", 0, 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.apache.xml.security.algorithms.implementations.SignatureDSA;
import org.apache.xml.security.algorithms.implementations.SignatureECDSA;
import org.apache.xml.security.algorithms.implementations.SignatureEDDSA;
import org.apache.xml.security.algorithms.implementations.SignatureMLDSA;
import org.apache.xml.security.exceptions.AlgorithmAlreadyRegisteredException;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.signature.XMLSignature;
Expand Down Expand Up @@ -513,6 +514,15 @@ public static void registerDefaultAlgorithms() {
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448, SignatureEDDSA.SignatureEd448.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_MLDSA_44, SignatureMLDSA.SignatureMLDSA44.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_MLDSA_65, SignatureMLDSA.SignatureMLDSA65.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_SIGNATURE_MLDSA_87, SignatureMLDSA.SignatureMLDSA87.class
);
algorithmHash.put(
XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5, IntegrityHmac.IntegrityHmacMD5.class
);
Expand Down
Loading
Loading