adoptium-support icon indicating copy to clipboard operation
adoptium-support copied to clipboard

XML Namespace declaration missing in input for digest when adding SignatureProperties

Open mholschbach opened this issue 2 months ago • 3 comments

Please provide a brief summary of the bug

I'm using the XMLSignatureFactory to create a Signature with SignatureProperties. The SignatureProperty contains a Timestamp element from this namespace "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd".

When the digest computation of this SignatureProperty is prepared, the namespace is not added during the canonicalisation and a wrong digest is computed.

Did you test with the latest update version?

  • [x] Yes

Please provide steps to reproduce where possible

This is a sanitized version of the source code with some parts removed and static values used for the SignatureProperties so the digest values are static. The XML output looks perfectly fine, with the exception of the DigestValue for the Reference to the SignatureProperty.

I tried to follow the Canonicalizer in debug mode. The elements Timestamp and Created have their namespace set, but the namespace doesn't exist in some "visibly" structure. The Signature I compute also contains other Reference elements whose digests are computed correctly with the expected namespace declarations. I looked for differences while in debug mode but I found nothing obvious.

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
// Document is parsed from the result of an XSL Transformation
Document doc = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");

Preparing the SignatureProperties with a Timestamp element and Created child, which both use the namespace prefix ns1 for their namespace.

String timestampNS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";        
Element timestamp = doc.createElementNS(timestampNS, "ns1:Timestamp");                
String created = "2025-08-05T13:49:29+00:00";
timestamp.appendChild(doc.createElementNS(timestampNS, "ns1:Created")).setTextContent(created);
DOMStructure domTimestamp = new DOMStructure(timestamp);
String signatureId = "Signature_d69345d0-6912-4027-82ee-3cf8baaa3f95";
String sigPropId = "SignatureProperty_3205bd06-4f89-4c91-a99d-36bba026b8f3";
SignatureProperty sigProp = factory.newSignatureProperty
    (Collections.singletonList(domTimestamp), "#"+signatureId, sigPropId);
SignatureProperties sigProps = factory.newSignatureProperties
    (Collections.singletonList(sigProp), null);

Adding a Reference for the SignatureProperty

Reference sigprop_reference = factory.newReference
    ("#"+sigPropId,
     factory.newDigestMethod(DigestMethod.SHA256, null),
     Collections.singletonList
         (factory.newTransform
             (CanonicalizationMethod.EXCLUSIVE,
              (TransformParameterSpec) null)),
     null, null);

add Manifest and SignatureProperties to the list of Object elements

List<XMLObject> xmlObjectList = new ArrayList<XMLObject>();
xmlObjectList.add(factory.newXMLObject(Collections.singletonList(manifest), null, null, null));
xmlObjectList.add(factory.newXMLObject(Collections.singletonList(sigProps), null, null, null));

Preparing the SignedInfo element

SignedInfo signedInfo = factory.newSignedInfo
            (factory.newCanonicalizationMethod
                 (CanonicalizationMethod.EXCLUSIVE,
                  (C14NMethodParameterSpec) null),
             factory.newSignatureMethod(SignatureMethod.RSA_SHA256, null),
             Arrays.asList(mb_reference, manifest_reference, sigprop_reference)
             );

Creating SignContext and sign, providing the SignedInfo with the Reference elements and the xmlObjectList, ki is the KeyInfo of an X509Certificate

        DOMSignContext dsc = new DOMSignContext
            (keyPair.getPrivate(),
             doc.getDocumentElement()
             ,doc.getDocumentElement().getFirstChild()); // to insert Signature before existing first child of the root element

        XMLSignature signature = factory.newXMLSignature(signedInfo, ki, xmlObjectList, signatureId, null);        
        signature.sign(dsc);

Expected Results

Above code creates this as part of the final output, which is as expected: <Object><SignatureProperties><SignatureProperty Id="SignatureProperty_3205bd06-4f89-4c91-a99d-36bba026b8f3" Target="#Signature_d69345d0-6912-4027-82ee-3cf8baaa3f95"><ns1:Timestamp xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><ns1:Created>2025-08-05T13:49:29+00:00</ns1:Created></ns1:Timestamp></SignatureProperty></SignatureProperties></Object>

Expected input to the digest computation is: <SignatureProperty xmlns="http://www.w3.org/2000/09/xmldsig#" Id="SignatureProperty_3205bd06-4f89-4c91-a99d-36bba026b8f3" Target="#Signature_d69345d0-6912-4027-82ee-3cf8baaa3f95"><ns1:Timestamp xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><ns1:Created>2025-08-05T13:49:29+00:00</ns1:Created></ns1:Timestamp></SignatureProperty> with this DigestValue OTrkBPF56k+HHldEGQtYBRUgA3XD7FaWRS5jV/2/5Ds=

Actual Results

Actual input to the digest computation is: <SignatureProperty xmlns="http://www.w3.org/2000/09/xmldsig#" Id="SignatureProperty_3205bd06-4f89-4c91-a99d-36bba026b8f3" Target="#Signature_d69345d0-6912-4027-82ee-3cf8baaa3f95"><ns1:Timestamp><ns1:Created>2025-08-05T13:49:29+00:00</ns1:Created></ns1:Timestamp></SignatureProperty> with this DigestValue JcFNsDbGHWMdXI5vJGRvJZ6AxRqO4gZ8kHaDQQ9p8Lw=

The namespace declaration for the Timestamp element is missing.

What Java Version are you using?

openjdk 25 2025-09-16 LTS OpenJDK Runtime Environment Temurin-25+36 (build 25+36-LTS) OpenJDK 64-Bit Server VM Temurin-25+36 (build 25+36-LTS, mixed mode, sharing)

What is your operating system and platform?

Ubuntu 24.04 on x86_64

How did you install Java?

temurin-25-jdk from this package repository

deb https://packages.adoptium.net/artifactory/deb noble main

Did it work before?


Did you test with other Java versions?

Tested also with 21, switched to 25 today in case my issue was already fixed.

openjdk version "21.0.8" 2025-07-15 LTS
OpenJDK Runtime Environment Temurin-21.0.8+9 (build 21.0.8+9-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.8+9 (build 21.0.8+9-LTS, mixed mode, sharing)

Relevant log output


mholschbach avatar Sep 24 '25 09:09 mholschbach

Attached is a fully working java program that produces the described output.

GenEnveloped.java

mholschbach avatar Sep 24 '25 12:09 mholschbach

FYI, issue received this bug id: https://bugs.java.com/bugdatabase/view_bug?bug_id=JDK-8368678

mholschbach avatar Sep 25 '25 14:09 mholschbach

Thanks. https://bugs.openjdk.org/browse/JDK-8368678 is a link with a more readable format to JDK devs.

jerboaa avatar Sep 25 '25 18:09 jerboaa