Robert P
Robert P

Reputation: 9793

XML Signature Reference digest uses parent namespace

I need to sign an XML-File in Java, which needs to contain 3 References.
While 2 of them are valid (expected digest == actual digest), one is invalid.
The relevant part of the XML Looks like:

<QualifyingProperties xmlns="http://uri.etsi.org/01903/v1.3.2#" Target="Signature1">
    <SignedProperties Id="SignedProperties_1">
        <SignedSignatureProperties>
            <SigningTime>2014-11-27T13:49:36</SigningTime>
        </SignedSignatureProperties>
    </SignedProperties>
</QualifyingProperties>

The Reference only references the Element "SignedProperties" and its children.
As you can see the "QualifyingProperties" Element defines a namespace (xmlns="http://uri.etsi.org/01903/v1.3.2#") and i guess thats the problem:

After having a look at the log i found, that the "Pre-Digest" Value looks like:

<SignedProperties xmlns="http://uri.etsi.org/01903/v1.3.2#" Id="SignedProperties_1">
    <SignedSignatureProperties>
        <SigningTime>2014-11-27T13:49:36</SigningTime>
    </SignedSignatureProperties>
</SignedProperties>

While the "SignedProperties" Element in the real file does not contain the namespace, but its parent does.
I found out, that the actual digest matches the SHA-256 of the "Pre-Digest" value, while the expected digest matches the SHA-256 of the real file (without the namespace).

The Reference is created with the following code:

Reference sigPropRef = fac.newReference("#SignedProperties_1", fac.newDigestMethod(DigestMethod.SHA256, null),
    Collections.singletonList(sigPropTransform), "http://uri.etsi.org/01903#SignedProperties", "reference-signedpropeties"
);

Where the sigPropTransform is a CanonicalizationMethod.EXCLUSIVE Transform.

My question is, how can i solve the problem, i.e. how can i prevent the namespace to be added to the "SignedProperties" Element, before calculating the digest?

If you need any other informations please leave a comment, i am pretty new to this theme, so i am not sure which informations are relevant and which not.
Thanks a lot!

EDIT: After playing arround a bit, it seems to me, that the "actual digest" is the digest, the validator calculated, while the "expected digest" is the digest inside the "DigestValue" Element.
That means, that the digest value inside my file matches the SHA-256 of the referenced filepart, but the validator for some reason calculates the digest WITh the parents namespace.
So i guess what i need is to include the parents namespace in my digest calculation.

EDIT: I continued playing arround and now i have not only the Pre-Digest value of the validator but also the one of my "digest calculation".
That one gives me:

<SignedProperties Id="SignedProperties_1"><SignedSignatureProperties><SigningTime>2014-11-27T15:51:26</SigningTime></SignedSignatureProperties></SignedProperties>  

when i give it the following Transform:

Transform sigPropTransform = fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (ExcC14NParameterSpec)null);  

And:

<SignedProperties xmlns:ds="some-url" xmlns:msg="some-other-url" Id="SignedProperties_1"><SignedSignatureProperties><SigningTime>2014-11-27T15:52:49</SigningTime></SignedSignatureProperties></SignedProperties>

when i don't give it any Transform.
The namespace xmlns="http://uri.etsi.org/01903/v1.3.2#" is never included.

How do i include it?

Upvotes: 0

Views: 1890

Answers (2)

Robert P
Robert P

Reputation: 9793

After a few more tries i finally found the actuall problem, as well as the solution:
As i allready stated in the question, the digest calculation did not use the parents namespace, defined as xmlns="http://uri.etsi.org/01903/v1.3.2#".
This was, because i did never "register" it as a namespace, but i only added it as a normal Attribute. To "register" the namespace i need to call setAttributeNS instead of setAttribute.
The code then looks something like:

Element eQualifyingProperties= doc.createElement("QualifyingProperties");
eQualifyingProperties.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "http://uri.etsi.org/01903/v1.3.2#");   

The first parameter is the namespace-uri of the Attribute and since the Attribute is a namespace it is the URI of the XML-Namespaces.
The second parameter is the attribute-name, since it should not have any praefix it is simply "xmlns".
The third parameter is the actual attibute-value, which is the namespace-uri i want to "register".
The Element eQualifyingProperties is the parent of the "SignedProperties" Element.

After registering the namespace as a real namespace (not as an attribute), the defined Transform

Transform sigPropTransform = fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (ExcC14NParameterSpec)null);  

includes it in the digest calculation.

I found this solution in this answer on SO.

Upvotes: 0

rzysia
rzysia

Reputation: 737

I'm afraid that you cannot prevent adding a namespace - it's being add during canonicalizaton. This one helped me when i had identical issue ;)

Upvotes: 1

Related Questions