You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by "ffang (via GitHub)" <gi...@apache.org> on 2026/08/07 15:45:53 UTC

[PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

ffang opened a new pull request, #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645

   …ryption
   
   - ML-DSA (FIPS 204): signature algorithm constants for ML-DSA-44/65/87, JCA mappings and whitelist URIs in XMLSignature, DOM and JSR-105 support.
   
   - ML-KEM (FIPS 203): key transport support using the W3C "XML Security: Generic Hybrid Cipher" structure (https://www.w3.org/TR/xmlsec-generic-hybrid/, closing SANTUARIO-633): KeyUtils.kemEncapsulate/kemDecapsulate perform real javax.crypto.KEM (JEP 452) encapsulation/decapsulation plus HKDF key derivation, with the AES-KeyWrap output and KEM encapsulation concatenated into CipherValue. New ALGO_ID_KEYTRANSPORT_GENERIC_HYBRID top-level algorithm and GenericHybridCipherMethod/KeyEncapsulationMethod/ DataEncapsulationMethod XML structure, wired into both the DOM XMLCipher and STAX (XMLEncryptOutputProcessor/XMLEncryptedKeyInputHandler) paths.
   
   - Both features require BouncyCastle 1.84+ and skip gracefully without it; ML-KEM additionally requires Java 21+ for javax.crypto.KEM, accessed via reflection so the module still compiles under its Java 11 target.
   
   Algorithm URIs follow the RFC 9231 provisional naming pattern under http://www.w3.org/tbd# per draft-eastlake-rfc9231bis-xmlsec-uris, pending final URI assignment.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5255700355

   Thank you for this contribution! I plan on reviewing this but will need a couple of weeks.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "github-advanced-security[bot] (via GitHub)" <gi...@apache.org>.
github-advanced-security[bot] commented on code in PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#discussion_r3736985198


##########
src/main/java/org/apache/xml/security/algorithms/implementations/SignatureMLDSA.java:
##########
@@ -0,0 +1,208 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.algorithms.implementations;
+
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.algorithms.SignatureAlgorithmSpi;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.utils.XMLUtils;
+
+/**
+ * ML-DSA (FIPS 204) signature algorithm implementation for XML-Dsig.
+ * Supports ML-DSA-44 (NIST security level 2), ML-DSA-65 (level 3),
+ * and ML-DSA-87 (level 5). Requires BouncyCastle 1.81+ as the JCA provider.
+ */
+public abstract class SignatureMLDSA extends SignatureAlgorithmSpi {
+
+    private static final Logger LOG = System.getLogger(SignatureMLDSA.class.getName());
+
+    private final Signature signatureAlgorithm;
+
+    public SignatureMLDSA() throws XMLSignatureException {
+        this(null);
+    }
+
+    public SignatureMLDSA(Provider provider) throws XMLSignatureException {
+        String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
+        LOG.log(Level.DEBUG, "Created SignatureMLDSA using {0}", algorithmID);
+
+        try {
+            if (provider == null) {
+                String providerId = JCEMapper.getProviderId();
+                if (providerId == null) {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID);
+                } else {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID, providerId);

Review Comment:
   ## CodeQL / Use of a broken or risky cryptographic algorithm
   
   Cryptographic algorithm [DESede/CBC/ISO10126Padding](1) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   Cryptographic algorithm [DESedeWrap](2) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1257)



##########
src/main/java/org/apache/xml/security/algorithms/implementations/SignatureMLDSA.java:
##########
@@ -0,0 +1,208 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.algorithms.implementations;
+
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.algorithms.SignatureAlgorithmSpi;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.utils.XMLUtils;
+
+/**
+ * ML-DSA (FIPS 204) signature algorithm implementation for XML-Dsig.
+ * Supports ML-DSA-44 (NIST security level 2), ML-DSA-65 (level 3),
+ * and ML-DSA-87 (level 5). Requires BouncyCastle 1.81+ as the JCA provider.
+ */
+public abstract class SignatureMLDSA extends SignatureAlgorithmSpi {
+
+    private static final Logger LOG = System.getLogger(SignatureMLDSA.class.getName());
+
+    private final Signature signatureAlgorithm;
+
+    public SignatureMLDSA() throws XMLSignatureException {
+        this(null);
+    }
+
+    public SignatureMLDSA(Provider provider) throws XMLSignatureException {
+        String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
+        LOG.log(Level.DEBUG, "Created SignatureMLDSA using {0}", algorithmID);
+
+        try {
+            if (provider == null) {
+                String providerId = JCEMapper.getProviderId();
+                if (providerId == null) {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID);

Review Comment:
   ## CodeQL / Use of a broken or risky cryptographic algorithm
   
   Cryptographic algorithm [DESede/CBC/ISO10126Padding](1) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   Cryptographic algorithm [DESedeWrap](2) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1256)



##########
src/main/java/org/apache/xml/security/algorithms/implementations/SignatureMLDSA.java:
##########
@@ -0,0 +1,208 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.algorithms.implementations;
+
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.algorithms.SignatureAlgorithmSpi;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.utils.XMLUtils;
+
+/**
+ * ML-DSA (FIPS 204) signature algorithm implementation for XML-Dsig.
+ * Supports ML-DSA-44 (NIST security level 2), ML-DSA-65 (level 3),
+ * and ML-DSA-87 (level 5). Requires BouncyCastle 1.81+ as the JCA provider.
+ */
+public abstract class SignatureMLDSA extends SignatureAlgorithmSpi {
+
+    private static final Logger LOG = System.getLogger(SignatureMLDSA.class.getName());
+
+    private final Signature signatureAlgorithm;
+
+    public SignatureMLDSA() throws XMLSignatureException {
+        this(null);
+    }
+
+    public SignatureMLDSA(Provider provider) throws XMLSignatureException {
+        String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
+        LOG.log(Level.DEBUG, "Created SignatureMLDSA using {0}", 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);

Review Comment:
   ## CodeQL / Use of a potentially broken or risky cryptographic algorithm
   
   Cryptographic algorithm [MD5](1) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RIPEMD160](2) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-1](3) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-224](4) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [WHIRLPOOL](5) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA3-224](6) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA1withDSA](7) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RSASSA-PSS](8) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-44](9) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-65](10) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-87](11) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacMD5](12) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HMACRIPEMD160](13) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacSHA224](14) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEED/CBC/ISO10126Padding](15) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](16) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](17) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](18) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-512](19) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-768](20) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-1024](21) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](22) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](23) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](24) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](25) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](26) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](27) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEEDWrap](28) may not be secure. Consider using a different algorithm.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1263)



##########
src/main/java/org/apache/xml/security/stax/impl/processor/input/XMLEncryptedKeyInputHandler.java:
##########
@@ -260,6 +270,100 @@
                             return this.decryptedKey;
                         }
                     }
+
+                    /**
+                     * Decapsulate/unwrap a CEK transported via KEM-based (Generic Hybrid Cipher) key
+                     * transport, per https://www.w3.org/TR/xmlsec-generic-hybrid/ (see SANTUARIO-633).
+                     * The {@code ghc:GenericHybridCipherMethod} element has no JAXB binding, so it is
+                     * read back as a raw DOM {@link Element} from the wildcard EncryptionMethod content
+                     * and parsed with the same DOM classes ({@link KeyDerivationMethodImpl},
+                     * {@link XMLCipherUtil}) used by the DOM {@code XMLCipher} API for the same structure.
+                     */
+                    private byte[] getGenericHybridSecret(InboundSecurityToken wrappingSecurityToken, String correlationID,
+                                                           XMLSecurityConstants.AlgorithmUsage algorithmUsage,
+                                                           String symmetricAlgorithmURI) throws XMLSecurityException {
+                        try {
+                            Element genericHybridCipherMethodElement = findAnyElement(
+                                    encryptedKeyType.getEncryptionMethod().getContent(),
+                                    XMLSecurityConstants.TAG_ghc_GenericHybridCipherMethod);
+                            if (genericHybridCipherMethodElement == null) {
+                                throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                            }
+
+                            Element keyEncapsulationMethodElement = (Element) genericHybridCipherMethodElement
+                                    .getElementsByTagNameNS(XMLSecurityConstants.NS_GHC, "KeyEncapsulationMethod").item(0);
+                            Element dataEncapsulationMethodElement = (Element) genericHybridCipherMethodElement
+                                    .getElementsByTagNameNS(XMLSecurityConstants.NS_GHC, "DataEncapsulationMethod").item(0);
+                            if (keyEncapsulationMethodElement == null || dataEncapsulationMethodElement == null) {
+                                throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                            }
+
+                            String kemAlgorithm = keyEncapsulationMethodElement.getAttributeNS(null, "Algorithm");
+                            String dataEncapsulationAlgorithm = dataEncapsulationMethodElement.getAttributeNS(null, "Algorithm");
+
+                            Element keyDerivationMethodElement = (Element) keyEncapsulationMethodElement
+                                    .getElementsByTagNameNS(XMLSecurityConstants.NS_XMLENC11, "KeyDerivationMethod").item(0);
+                            if (keyDerivationMethodElement == null) {
+                                throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                            }
+
+                            int wrapKeyBitLength = KeyUtils.getAESKeyBitSizeForWrapAlgorithm(dataEncapsulationAlgorithm);
+                            KeyDerivationMethodImpl keyDerivationMethod = new KeyDerivationMethodImpl(keyDerivationMethodElement, null);
+                            KeyDerivationParameters kdp = XMLCipherUtil.constructKeyDerivationParameter(keyDerivationMethod, wrapKeyBitLength);
+
+                            Key wrapKeyToken = wrappingSecurityToken.getSecretKey(kemAlgorithm, algorithmUsage, correlationID);
+                            if (!(wrapKeyToken instanceof PrivateKey)) {
+                                throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                            }
+
+                            if (encryptedKeyType.getCipherData() == null
+                                    || encryptedKeyType.getCipherData().getCipherValue() == null
+                                    || encryptedKeyType.getCipherData().getCipherValue().getContent() == null
+                                    || encryptedKeyType.getCipherData().getCipherValue().getContent().isEmpty()) {
+                                throw new XMLSecurityException("stax.encryption.noCipherValue");
+                            }
+
+                            byte[] encryptedBytes = getEncryptedBytes(encryptedKeyType.getCipherData().getCipherValue());
+                            byte[] sha1Bytes = generateDigest(encryptedBytes);
+                            String sha1Identifier = XMLUtils.encodeToString(sha1Bytes);
+                            super.setSha1Identifier(sha1Identifier);
+
+                            try {
+                                KeyUtils.KemDecapsulation kemResult = KeyUtils.kemDecapsulate(
+                                        (PrivateKey) wrapKeyToken, kemAlgorithm, encryptedBytes, kdp);
+                                String jceWrapId = JCEMapper.translateURItoJCEID(dataEncapsulationAlgorithm);
+                                Cipher cipher = Cipher.getInstance(jceWrapId);

Review Comment:
   ## CodeQL / Use of a broken or risky cryptographic algorithm
   
   Cryptographic algorithm [DESede/CBC/ISO10126Padding](1) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   Cryptographic algorithm [DESedeWrap](2) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1259)



##########
src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java:
##########
@@ -265,10 +292,111 @@
 
                         createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherValue);
                         createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherData);
+                    }
 
-                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptedKey);
+                    /**
+                     * Writes the EncryptionMethod/KeyInfo/CipherData for KEM-based (Generic Hybrid Cipher)
+                     * key transport, per https://www.w3.org/TR/xmlsec-generic-hybrid/ section 6.1
+                     * "Key Transport Example" (see SANTUARIO-633).
+                     */
+                    private void createGenericHybridCipherKeyInfoStructure(
+                            OutputProcessorChain outputProcessorChain, PublicKey pubKey)
+                            throws XMLStreamException, XMLSecurityException {
 
-                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo);
+                        String kemAlgorithm = getSecurityProperties().getEncryptionKeyEncapsulationAlgorithm();
+                        String dataEncapsulationAlgorithm = getSecurityProperties().getEncryptionDataEncapsulationAlgorithm();
+                        if (kemAlgorithm == null || dataEncapsulationAlgorithm == null) {
+                            throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                        }
+                        String hmacAlgorithm = getSecurityProperties().getEncryptionKeyEncapsulationHmacAlgorithm();
+                        if (hmacAlgorithm == null) {
+                            hmacAlgorithm = XMLSecurityConstants.NS_XMLDSIG_HMACSHA256;
+                        }
+
+                        int wrapKeyBitLength = KeyUtils.getAESKeyBitSizeForWrapAlgorithm(dataEncapsulationAlgorithm);
+                        KeyDerivationParameters kdfParams = HKDFParams.createBuilder(wrapKeyBitLength, hmacAlgorithm).build();
+
+                        // EncryptionMethod/ghc:GenericHybridCipherMethod/ghc:KeyEncapsulationMethod/...
+                        List<XMLSecAttribute> attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm,
+                                EncryptionConstants.ALGO_ID_KEYTRANSPORT_GENERIC_HYBRID));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptionMethod, false, attributes);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_GenericHybridCipherMethod, true, null);
+
+                        attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, kemAlgorithm));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_KeyEncapsulationMethod, true, attributes);
+
+                        attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, XMLSecurityConstants.NS_HKDF));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc11_KeyDerivationMethod, true, attributes);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_HKDFParams, true, null);
+
+                        attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, hmacAlgorithm));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_PRF, true, attributes);
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_PRF);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_KeyLength, false, null);
+                        createCharactersAndOutputAsEvent(outputProcessorChain, String.valueOf(wrapKeyBitLength / 8));
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_KeyLength);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_HKDFParams);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc11_KeyDerivationMethod);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_KeyLen, false, null);
+                        createCharactersAndOutputAsEvent(outputProcessorChain, String.valueOf(wrapKeyBitLength / 8));
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_KeyLen);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_KeyEncapsulationMethod);
+
+                        attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, dataEncapsulationAlgorithm));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_DataEncapsulationMethod, true, attributes);
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_DataEncapsulationMethod);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_GenericHybridCipherMethod);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptionMethod);
+
+                        createKeyInfoStructureForEncryptedKey(outputProcessorChain, keyWrappingToken);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherData, false, null);
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherValue, false, null);
+
+                        String tokenId = outputProcessorChain.getSecurityContext().get(
+                                XMLSecurityConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
+                        SecurityTokenProvider<OutboundSecurityToken> securityTokenProvider =
+                                outputProcessorChain.getSecurityContext().getSecurityTokenProvider(tokenId);
+                        final OutboundSecurityToken securityToken = securityTokenProvider.getSecurityToken();
+                        Key sessionKey = securityToken.getSecretKey(getSecurityProperties().getEncryptionSymAlgorithm());
+
+                        // Encapsulate a shared secret to the recipient's KEM public key, derive the
+                        // AES key-wrap key from it, and wrap the CEK with that key. CipherValue holds
+                        // the concatenation of the KEM encapsulation (C0) and the wrapped CEK (C1).
+                        KeyUtils.KemEncapsulation kemResult = KeyUtils.kemEncapsulate(pubKey, kemAlgorithm, kdfParams);
+                        try {
+                            String jceWrapId = JCEMapper.translateURItoJCEID(dataEncapsulationAlgorithm);
+                            Cipher wrapCipher = Cipher.getInstance(jceWrapId);

Review Comment:
   ## CodeQL / Use of a potentially broken or risky cryptographic algorithm
   
   Cryptographic algorithm [MD5](1) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RIPEMD160](2) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-1](3) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-224](4) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [WHIRLPOOL](5) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA3-224](6) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA1withDSA](7) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RSASSA-PSS](8) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-44](9) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-65](10) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-87](11) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacMD5](12) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HMACRIPEMD160](13) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacSHA224](14) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEED/CBC/ISO10126Padding](15) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](16) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](17) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](18) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-512](19) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-768](20) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-1024](21) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](22) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](23) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](24) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](25) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](26) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](27) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEEDWrap](28) may not be secure. Consider using a different algorithm.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1265)



##########
src/main/java/org/apache/xml/security/algorithms/implementations/SignatureMLDSA.java:
##########
@@ -0,0 +1,208 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.algorithms.implementations;
+
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.algorithms.SignatureAlgorithmSpi;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.utils.XMLUtils;
+
+/**
+ * ML-DSA (FIPS 204) signature algorithm implementation for XML-Dsig.
+ * Supports ML-DSA-44 (NIST security level 2), ML-DSA-65 (level 3),
+ * and ML-DSA-87 (level 5). Requires BouncyCastle 1.81+ as the JCA provider.
+ */
+public abstract class SignatureMLDSA extends SignatureAlgorithmSpi {
+
+    private static final Logger LOG = System.getLogger(SignatureMLDSA.class.getName());
+
+    private final Signature signatureAlgorithm;
+
+    public SignatureMLDSA() throws XMLSignatureException {
+        this(null);
+    }
+
+    public SignatureMLDSA(Provider provider) throws XMLSignatureException {
+        String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
+        LOG.log(Level.DEBUG, "Created SignatureMLDSA using {0}", algorithmID);
+
+        try {
+            if (provider == null) {
+                String providerId = JCEMapper.getProviderId();
+                if (providerId == null) {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID);

Review Comment:
   ## CodeQL / Use of a potentially broken or risky cryptographic algorithm
   
   Cryptographic algorithm [MD5](1) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RIPEMD160](2) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-1](3) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-224](4) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [WHIRLPOOL](5) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA3-224](6) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA1withDSA](7) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RSASSA-PSS](8) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-44](9) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-65](10) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-87](11) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacMD5](12) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HMACRIPEMD160](13) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacSHA224](14) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEED/CBC/ISO10126Padding](15) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](16) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](17) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](18) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-512](19) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-768](20) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-1024](21) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](22) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](23) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](24) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](25) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](26) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](27) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEEDWrap](28) may not be secure. Consider using a different algorithm.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1261)



##########
src/main/java/org/apache/xml/security/algorithms/implementations/SignatureMLDSA.java:
##########
@@ -0,0 +1,208 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.algorithms.implementations;
+
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.algorithms.SignatureAlgorithmSpi;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.utils.XMLUtils;
+
+/**
+ * ML-DSA (FIPS 204) signature algorithm implementation for XML-Dsig.
+ * Supports ML-DSA-44 (NIST security level 2), ML-DSA-65 (level 3),
+ * and ML-DSA-87 (level 5). Requires BouncyCastle 1.81+ as the JCA provider.
+ */
+public abstract class SignatureMLDSA extends SignatureAlgorithmSpi {
+
+    private static final Logger LOG = System.getLogger(SignatureMLDSA.class.getName());
+
+    private final Signature signatureAlgorithm;
+
+    public SignatureMLDSA() throws XMLSignatureException {
+        this(null);
+    }
+
+    public SignatureMLDSA(Provider provider) throws XMLSignatureException {
+        String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
+        LOG.log(Level.DEBUG, "Created SignatureMLDSA using {0}", 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);

Review Comment:
   ## CodeQL / Use of a broken or risky cryptographic algorithm
   
   Cryptographic algorithm [DESede/CBC/ISO10126Padding](1) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   Cryptographic algorithm [DESedeWrap](2) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1258)



##########
src/main/java/org/apache/xml/security/algorithms/implementations/SignatureMLDSA.java:
##########
@@ -0,0 +1,208 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.algorithms.implementations;
+
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.algorithms.SignatureAlgorithmSpi;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.utils.XMLUtils;
+
+/**
+ * ML-DSA (FIPS 204) signature algorithm implementation for XML-Dsig.
+ * Supports ML-DSA-44 (NIST security level 2), ML-DSA-65 (level 3),
+ * and ML-DSA-87 (level 5). Requires BouncyCastle 1.81+ as the JCA provider.
+ */
+public abstract class SignatureMLDSA extends SignatureAlgorithmSpi {
+
+    private static final Logger LOG = System.getLogger(SignatureMLDSA.class.getName());
+
+    private final Signature signatureAlgorithm;
+
+    public SignatureMLDSA() throws XMLSignatureException {
+        this(null);
+    }
+
+    public SignatureMLDSA(Provider provider) throws XMLSignatureException {
+        String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
+        LOG.log(Level.DEBUG, "Created SignatureMLDSA using {0}", algorithmID);
+
+        try {
+            if (provider == null) {
+                String providerId = JCEMapper.getProviderId();
+                if (providerId == null) {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID);
+                } else {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID, providerId);

Review Comment:
   ## CodeQL / Use of a potentially broken or risky cryptographic algorithm
   
   Cryptographic algorithm [MD5](1) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RIPEMD160](2) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-1](3) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-224](4) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [WHIRLPOOL](5) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA3-224](6) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA1withDSA](7) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RSASSA-PSS](8) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-44](9) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-65](10) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-87](11) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacMD5](12) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HMACRIPEMD160](13) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacSHA224](14) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEED/CBC/ISO10126Padding](15) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](16) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](17) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](18) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-512](19) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-768](20) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-1024](21) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](22) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](23) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](24) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](25) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](26) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](27) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEEDWrap](28) may not be secure. Consider using a different algorithm.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1262)



##########
src/main/java/org/apache/xml/security/stax/impl/processor/input/XMLEncryptedKeyInputHandler.java:
##########
@@ -260,6 +270,100 @@
                             return this.decryptedKey;
                         }
                     }
+
+                    /**
+                     * Decapsulate/unwrap a CEK transported via KEM-based (Generic Hybrid Cipher) key
+                     * transport, per https://www.w3.org/TR/xmlsec-generic-hybrid/ (see SANTUARIO-633).
+                     * The {@code ghc:GenericHybridCipherMethod} element has no JAXB binding, so it is
+                     * read back as a raw DOM {@link Element} from the wildcard EncryptionMethod content
+                     * and parsed with the same DOM classes ({@link KeyDerivationMethodImpl},
+                     * {@link XMLCipherUtil}) used by the DOM {@code XMLCipher} API for the same structure.
+                     */
+                    private byte[] getGenericHybridSecret(InboundSecurityToken wrappingSecurityToken, String correlationID,
+                                                           XMLSecurityConstants.AlgorithmUsage algorithmUsage,
+                                                           String symmetricAlgorithmURI) throws XMLSecurityException {
+                        try {
+                            Element genericHybridCipherMethodElement = findAnyElement(
+                                    encryptedKeyType.getEncryptionMethod().getContent(),
+                                    XMLSecurityConstants.TAG_ghc_GenericHybridCipherMethod);
+                            if (genericHybridCipherMethodElement == null) {
+                                throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                            }
+
+                            Element keyEncapsulationMethodElement = (Element) genericHybridCipherMethodElement
+                                    .getElementsByTagNameNS(XMLSecurityConstants.NS_GHC, "KeyEncapsulationMethod").item(0);
+                            Element dataEncapsulationMethodElement = (Element) genericHybridCipherMethodElement
+                                    .getElementsByTagNameNS(XMLSecurityConstants.NS_GHC, "DataEncapsulationMethod").item(0);
+                            if (keyEncapsulationMethodElement == null || dataEncapsulationMethodElement == null) {
+                                throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                            }
+
+                            String kemAlgorithm = keyEncapsulationMethodElement.getAttributeNS(null, "Algorithm");
+                            String dataEncapsulationAlgorithm = dataEncapsulationMethodElement.getAttributeNS(null, "Algorithm");
+
+                            Element keyDerivationMethodElement = (Element) keyEncapsulationMethodElement
+                                    .getElementsByTagNameNS(XMLSecurityConstants.NS_XMLENC11, "KeyDerivationMethod").item(0);
+                            if (keyDerivationMethodElement == null) {
+                                throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                            }
+
+                            int wrapKeyBitLength = KeyUtils.getAESKeyBitSizeForWrapAlgorithm(dataEncapsulationAlgorithm);
+                            KeyDerivationMethodImpl keyDerivationMethod = new KeyDerivationMethodImpl(keyDerivationMethodElement, null);
+                            KeyDerivationParameters kdp = XMLCipherUtil.constructKeyDerivationParameter(keyDerivationMethod, wrapKeyBitLength);
+
+                            Key wrapKeyToken = wrappingSecurityToken.getSecretKey(kemAlgorithm, algorithmUsage, correlationID);
+                            if (!(wrapKeyToken instanceof PrivateKey)) {
+                                throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                            }
+
+                            if (encryptedKeyType.getCipherData() == null
+                                    || encryptedKeyType.getCipherData().getCipherValue() == null
+                                    || encryptedKeyType.getCipherData().getCipherValue().getContent() == null
+                                    || encryptedKeyType.getCipherData().getCipherValue().getContent().isEmpty()) {
+                                throw new XMLSecurityException("stax.encryption.noCipherValue");
+                            }
+
+                            byte[] encryptedBytes = getEncryptedBytes(encryptedKeyType.getCipherData().getCipherValue());
+                            byte[] sha1Bytes = generateDigest(encryptedBytes);
+                            String sha1Identifier = XMLUtils.encodeToString(sha1Bytes);
+                            super.setSha1Identifier(sha1Identifier);
+
+                            try {
+                                KeyUtils.KemDecapsulation kemResult = KeyUtils.kemDecapsulate(
+                                        (PrivateKey) wrapKeyToken, kemAlgorithm, encryptedBytes, kdp);
+                                String jceWrapId = JCEMapper.translateURItoJCEID(dataEncapsulationAlgorithm);
+                                Cipher cipher = Cipher.getInstance(jceWrapId);

Review Comment:
   ## CodeQL / Use of a potentially broken or risky cryptographic algorithm
   
   Cryptographic algorithm [MD5](1) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RIPEMD160](2) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-1](3) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA-224](4) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [WHIRLPOOL](5) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA3-224](6) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SHA1withDSA](7) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [RSASSA-PSS](8) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-44](9) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-65](10) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-DSA-87](11) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacMD5](12) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HMACRIPEMD160](13) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [HmacSHA224](14) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEED/CBC/ISO10126Padding](15) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](16) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](17) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [Camellia/CBC/ISO10126Padding](18) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-512](19) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-768](20) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [ML-KEM-1024](21) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](22) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](23) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [AESWrap](24) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](25) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](26) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [CamelliaWrap](27) may not be secure. Consider using a different algorithm.
   Cryptographic algorithm [SEEDWrap](28) may not be secure. Consider using a different algorithm.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1264)



##########
src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java:
##########
@@ -265,10 +292,111 @@
 
                         createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherValue);
                         createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherData);
+                    }
 
-                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptedKey);
+                    /**
+                     * Writes the EncryptionMethod/KeyInfo/CipherData for KEM-based (Generic Hybrid Cipher)
+                     * key transport, per https://www.w3.org/TR/xmlsec-generic-hybrid/ section 6.1
+                     * "Key Transport Example" (see SANTUARIO-633).
+                     */
+                    private void createGenericHybridCipherKeyInfoStructure(
+                            OutputProcessorChain outputProcessorChain, PublicKey pubKey)
+                            throws XMLStreamException, XMLSecurityException {
 
-                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo);
+                        String kemAlgorithm = getSecurityProperties().getEncryptionKeyEncapsulationAlgorithm();
+                        String dataEncapsulationAlgorithm = getSecurityProperties().getEncryptionDataEncapsulationAlgorithm();
+                        if (kemAlgorithm == null || dataEncapsulationAlgorithm == null) {
+                            throw new XMLSecurityException("stax.unsupportedKeyTransp");
+                        }
+                        String hmacAlgorithm = getSecurityProperties().getEncryptionKeyEncapsulationHmacAlgorithm();
+                        if (hmacAlgorithm == null) {
+                            hmacAlgorithm = XMLSecurityConstants.NS_XMLDSIG_HMACSHA256;
+                        }
+
+                        int wrapKeyBitLength = KeyUtils.getAESKeyBitSizeForWrapAlgorithm(dataEncapsulationAlgorithm);
+                        KeyDerivationParameters kdfParams = HKDFParams.createBuilder(wrapKeyBitLength, hmacAlgorithm).build();
+
+                        // EncryptionMethod/ghc:GenericHybridCipherMethod/ghc:KeyEncapsulationMethod/...
+                        List<XMLSecAttribute> attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm,
+                                EncryptionConstants.ALGO_ID_KEYTRANSPORT_GENERIC_HYBRID));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptionMethod, false, attributes);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_GenericHybridCipherMethod, true, null);
+
+                        attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, kemAlgorithm));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_KeyEncapsulationMethod, true, attributes);
+
+                        attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, XMLSecurityConstants.NS_HKDF));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc11_KeyDerivationMethod, true, attributes);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_HKDFParams, true, null);
+
+                        attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, hmacAlgorithm));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_PRF, true, attributes);
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_PRF);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_KeyLength, false, null);
+                        createCharactersAndOutputAsEvent(outputProcessorChain, String.valueOf(wrapKeyBitLength / 8));
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_KeyLength);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_hkdf_HKDFParams);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc11_KeyDerivationMethod);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_KeyLen, false, null);
+                        createCharactersAndOutputAsEvent(outputProcessorChain, String.valueOf(wrapKeyBitLength / 8));
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_KeyLen);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_KeyEncapsulationMethod);
+
+                        attributes = new ArrayList<>(1);
+                        attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, dataEncapsulationAlgorithm));
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_DataEncapsulationMethod, true, attributes);
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_DataEncapsulationMethod);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_ghc_GenericHybridCipherMethod);
+
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptionMethod);
+
+                        createKeyInfoStructureForEncryptedKey(outputProcessorChain, keyWrappingToken);
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherData, false, null);
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherValue, false, null);
+
+                        String tokenId = outputProcessorChain.getSecurityContext().get(
+                                XMLSecurityConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
+                        SecurityTokenProvider<OutboundSecurityToken> securityTokenProvider =
+                                outputProcessorChain.getSecurityContext().getSecurityTokenProvider(tokenId);
+                        final OutboundSecurityToken securityToken = securityTokenProvider.getSecurityToken();
+                        Key sessionKey = securityToken.getSecretKey(getSecurityProperties().getEncryptionSymAlgorithm());
+
+                        // Encapsulate a shared secret to the recipient's KEM public key, derive the
+                        // AES key-wrap key from it, and wrap the CEK with that key. CipherValue holds
+                        // the concatenation of the KEM encapsulation (C0) and the wrapped CEK (C1).
+                        KeyUtils.KemEncapsulation kemResult = KeyUtils.kemEncapsulate(pubKey, kemAlgorithm, kdfParams);
+                        try {
+                            String jceWrapId = JCEMapper.translateURItoJCEID(dataEncapsulationAlgorithm);
+                            Cipher wrapCipher = Cipher.getInstance(jceWrapId);

Review Comment:
   ## CodeQL / Use of a broken or risky cryptographic algorithm
   
   Cryptographic algorithm [DESede/CBC/ISO10126Padding](1) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   Cryptographic algorithm [DESedeWrap](2) is insecure. It has a short key length of 56 bits, making it vulnerable to brute-force attacks. Consider using AES instead.
   
   [Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1260)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "ffang (via GitHub)" <gi...@apache.org>.
ffang commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5318449428

   > I have been looking at post-quantum support across a number of Java crypto libraries and read through this PR with interest. Two choices in the KEM path stood out as the right ones: it takes the encapsulation length from the KEM API (Decapsulator.encapsulationSize()) rather than a hardcoded per-algorithm table, and it derives the key-wrap key through a KDF rather than using the raw shared secret.
   > 
   > One gap I noticed while reading the tests. The new PQC tests (XMLSignatureMLDSATest, XMLEncryptionMLKEMTest, StaxMLDSASignatureTest, StaxMLKEMEncryptionTest) all exercise the happy path only, sign-then-verify and encrypt-then-decrypt. For a signature and encryption feature it would be worth adding a few negative cases that lock in the security-relevant behaviour, for example:
   > 
   >     * a tampered ML-DSA signature (a flipped byte of SignatureValue) is rejected by verification;
   > 
   >     * an ML-DSA signature checked against the wrong public key fails;
   > 
   >     * ML-KEM decryption with the wrong recipient private key fails cleanly rather than returning wrong plaintext;
   > 
   >     * a truncated or corrupted KEM encapsulation (shorter than encapsulationSize, or a flipped byte) is rejected with a clear exception.
   > 
   > 
   > These are the cases that would catch a regression in the verify or decapsulate path later, and they are quick to add on top of the round-trip tests already there. Since you are planning to split this into separate Signature and Encryption PRs, the ML-DSA cases would go with the signature side and the ML-KEM cases with the encryption side. Happy to help with any of them if useful.
   
   Hi @Arpan0995 ,
   
   Thanks for the review, and glad the KEM length/KDF choices came through as intended.
   
   Good catch on the negative test coverage — you're right that the current tests only exercise the happy path. I'll send the split PRs (Signature and Encryption) soon and make sure to include the negative cases you listed: tampered signature rejection, wrong-key verification failure, wrong-key decryption failure, and truncated/corrupted encapsulation rejection.
   
   And yes, any help/contribution is welcome — feel free to jump in on either PR once they're up.
   
   Cheers
   Freeman


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "Arpan0995 (via GitHub)" <gi...@apache.org>.
Arpan0995 commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5317670857

   I have been looking at post-quantum support across a number of Java crypto libraries and read through this PR with interest. Two choices in the KEM path stood out as the right ones: it takes the encapsulation length from the KEM API (Decapsulator.encapsulationSize()) rather than a hardcoded per-algorithm table, and it derives the key-wrap key through a KDF rather than using the raw shared secret.
   
   One gap I noticed while reading the tests. The new PQC tests (XMLSignatureMLDSATest, XMLEncryptionMLKEMTest, StaxMLDSASignatureTest, StaxMLKEMEncryptionTest) all exercise the happy path only, sign-then-verify and encrypt-then-decrypt. For a signature and encryption feature it would be worth adding a few negative cases that lock in the security-relevant behaviour, for example:
   
   - a tampered ML-DSA signature (a flipped byte of SignatureValue) is rejected by verification;
   - an ML-DSA signature checked against the wrong public key fails;
   - ML-KEM decryption with the wrong recipient private key fails cleanly rather than returning wrong plaintext;
   - a truncated or corrupted KEM encapsulation (shorter than encapsulationSize, or a flipped byte) is rejected with a clear exception.
   
   These are the cases that would catch a regression in the verify or decapsulate path later, and they are quick to add on top of the round-trip tests already there. Since you are planning to split this into separate Signature and Encryption PRs, the ML-DSA cases would go with the signature side and the ML-KEM cases with the encryption side. Happy to help with any of them if useful.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "ffang (via GitHub)" <gi...@apache.org>.
ffang commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5259031388

   > Thank you for this contribution! I plan on reviewing this but will need a couple of weeks.
   
   Thanks @seanjmullan !
   
   No rush, take your time.
   
   Freeman


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "ffang (via GitHub)" <gi...@apache.org>.
ffang closed pull request #645: Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc…
URL: https://github.com/apache/santuario-xml-security-java/pull/645


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "bc-pi (via GitHub)" <gi...@apache.org>.
bc-pi commented on code in PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#discussion_r3823333157


##########
src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java:
##########
@@ -94,6 +94,16 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
         "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
     static final String ED448 =
         "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
+
+    // Provisional URIs for ML-DSA (FIPS 204) per draft-eastlake-rfc9231bis-xmlsec-uris
+    // section 3.3.15. These use the draft's "tbd" placeholder namespace and will need

Review Comment:
   https://www.w3.org/2026/08/xmldsig-more# is looking to be the clubhouse leader 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "Arpan0995 (via GitHub)" <gi...@apache.org>.
Arpan0995 commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5373459083

   Done: the rebased parameterization is up as ffang/santuario-xml-security-java#2 (ML-DSA, into #651) and ffang/santuario-xml-security-java#3 (ML-KEM, into #652).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5269884779

   I like the idea of splitting the PR into 2, one for XML Signature and one for XML Encryption. This will make it easier to focus on one specification at a time. And I think the XML Signature changes should be more straightforward.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "bc-pi (via GitHub)" <gi...@apache.org>.
bc-pi commented on code in PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#discussion_r3798464680


##########
src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java:
##########
@@ -94,6 +94,16 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
         "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
     static final String ED448 =
         "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
+
+    // Provisional URIs for ML-DSA (FIPS 204) per draft-eastlake-rfc9231bis-xmlsec-uris
+    // section 3.3.15. These use the draft's "tbd" placeholder namespace and will need

Review Comment:
   There's been some talk related to https://github.com/w3c/strategy/issues/484 about getting the namespace sorted so maybe coming soon. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "ffang (via GitHub)" <gi...@apache.org>.
ffang commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5371186621

   Per the discussion we separate this PR with other improvements as suggested here
   https://github.com/apache/santuario-xml-security-java/pull/652 (encryption)
   https://github.com/apache/santuario-xml-security-java/pull/651 (signature)
   So I close this one


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "ffang (via GitHub)" <gi...@apache.org>.
ffang commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5271572482

   > I like the idea of splitting the PR into 2, one for XML Signature and one for XML Encryption. This will make it easier to focus on one specification at a time. And I think the XML Signature changes should be more straightforward.
   
   Sure, I will separate the PR and resend.
   
   Cheers
   Freeman


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "ffang (via GitHub)" <gi...@apache.org>.
ffang commented on code in PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#discussion_r3798482252


##########
src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java:
##########
@@ -94,6 +94,16 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
         "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
     static final String ED448 =
         "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
+
+    // Provisional URIs for ML-DSA (FIPS 204) per draft-eastlake-rfc9231bis-xmlsec-uris
+    // section 3.3.15. These use the draft's "tbd" placeholder namespace and will need

Review Comment:
   Thanks for the heads-up @bc-pi !



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "ffang (via GitHub)" <gi...@apache.org>.
ffang commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5373731308

   > @ffang Done: the rebased parameterization is up as [ffang#2](https://github.com/ffang/santuario-xml-security-java/pull/2) (ML-DSA, into #651) and [ffang#3](https://github.com/ffang/santuario-xml-security-java/pull/3) (ML-KEM, into #652).
   
   Thanks @Arpan0995 ! Both are merged into my branches


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "ffang (via GitHub)" <gi...@apache.org>.
ffang commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5371162142

   > Arpan0995
   
   Hi @Arpan0995,
   
   Thanks for going ahead and implementing these — nice catch keeping them parameterized across all three parameter sets, that's cleaner than what I had.
   
   FYI, I'd already been working on adding negative-test coverage, and mine covers both the DOM and STAX paths . But your @ParameterizedTest/@CsvSource approach, parameterized across all three parameter sets, is cleaner than the single hardcoded case I used — I'd like to bring that in.
   
   The split PRs are up now:
   
   - #651 — ML-DSA (signature) — negative-test coverage on both the DOM/JSR-105 and STAX paths (tampered SignatureValue rejected, wrong public key rejected)
   - #652 — ML-KEM (encryption) — negative-test coverage on both the DOM and STAX paths (wrong recipient key fails cleanly, truncated EncryptedKey ciphertext rejected)
   
   Would you mind rebasing your parameterization against #651/#652 (ML-DSA cases → #651, ML-KEM cases → #652)? Happy to help however's easiest — a PR against my branch, or a patch pasted here.
   
   Cheers
   Freeman
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add PQC (ML-DSA and ML-KEM) support for XML Digital Signature and Enc… [santuario-xml-security-java]

Posted by "Arpan0995 (via GitHub)" <gi...@apache.org>.
Arpan0995 commented on PR #645:
URL: https://github.com/apache/santuario-xml-security-java/pull/645#issuecomment-5365492470

   Following up on the negative-test cases: since the split PRs are not up yet, I implemented the four cases against the current PQC branch and opened ffang/santuario-xml-security-java#1 into it, so they are ready before the split. All four are parameterized across the three parameter sets in the same style as the existing tests, pass locally with `mvn test -Dtest=XMLSignatureMLDSATest,XMLEncryptionMLKEMTest -P bouncycastle` (9 + 9 executions, 0 failures), and skip via the existing `assumeTrue` guards when BouncyCastle is absent. If you would rather fold them into the split PRs instead, the ML-DSA cases go with the Signature one and the ML-KEM cases with the Encryption one; happy to rebase either way.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org