That seems to work, though I used this code instead:
qualifyingPropertiesElement.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xades",
"http://uri.etsi.org/01903/v1.4.1#");
That's because my xades elements all carry that prefix. It does seem to
work. It's a bit odd to have to code it since the signed XML generates
it in the expected way, as does the signature validation code. In the
end, as long as it works, I'm happy again!
Thanks for all your help. After I try to push this back into our actual
code, I'll report back since I need to make sure that this works not
only on newly signed data using Java 11, but also continues to work on
previously signed content. I think it will from prior testing.
Thanks,
David
On 2/15/19 1:21 PM, Sean Mullan wrote:
I know what the problem is.
You also need to add the actual namespace attribute to your element,
for example:
qualifyingPropertiesElement.setAttributeNS(
"http://www.w3.org/2000/xmlns/", "xmlns",
"http://uri.etsi.org/01903/v1.1.1#");
You only need to do that on the top-most parent element in that namespace.
When I made that change to your code, everything generated and
verified for me correctly (on JDK 10 anyway, JDK 11 may still have
some issues).
--Sean
On 2/15/19 3:11 PM, Open eSignForms wrote:
XML namespaces are pretty confusing. From what little I gather,
unprefixed attributes don't belong to any namespace, not even the
default one.
I think I can see the bug in the debugging output.
On Java 8 and 10 and 11, I'd guess that the
marshaling/canonicalization has issues when combining differently
namespaced objects.
In my working code (also works on Java 11), when my ETSI/XADES
QualifyingProperties element is created specifying my namespace (the
default namespace for the XML document that I'm signing), it works
fine. If I change my document's default namespace to be the XADES
one, it also works. But I cannot make them work when both are in
use. The reason seems to be as follows.
1) The signedXML generated looks great and sensible, with the xades
namespace as expected.
<ds:Object>
<xades:QualifyingProperties Id="QualifyingProperties_ID"
Target="#OpenESignForms_Seal"
*xmlns:xades="http://uri.etsi.org/01903/v1.4.1#"*>
<xades:SignedProperties>
<xades:SignedSignatureProperties>
<xades:SigningTime>2019-02-15T11:30:44-08:00</xades:SigningTime>
</xades:SignedSignatureProperties>
<xades:SignedDataObjectProperties>
<xades:DataObjectFormat
ObjectReference="#Payload_Reference_ID">
<xades:Description>description</xades:Description>
<xades:MimeType>text/html</xades:MimeType>
</xades:DataObjectFormat>
</xades:SignedDataObjectProperties>
</xades:SignedProperties>
</xades:QualifyingProperties>
</ds:Object>
2) But using the debugging options, it shows this element during
SIGNING (presuming canonicalization) that makes /*no sense*/. It's
added both the default namespace, the 'dsig' namespace, but doesn't
include the xades namespace. Wwhat does the 'xades' prefix even refer
to in this XML for the signing digest?
<xades:QualifyingProperties
*xmlns="http://open.esignforms.com/XMLSchema/2011"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"*
Id="QualifyingProperties_ID" Target="#OpenESignForms_Seal">
<xades:SignedProperties>
<xades:SignedSignatureProperties>
<xades:SigningTime>2019-02-15T11:30:44-08:00</xades:SigningTime>
</xades:SignedSignatureProperties>
<xades:SignedDataObjectProperties>
<xades:DataObjectFormat
ObjectReference="#Payload_Reference_ID">
<xades:Description>description</xades:Description>
<xades:MimeType>text/html</xades:MimeType>
</xades:DataObjectFormat>
</xades:SignedDataObjectProperties>
</xades:SignedProperties>
</xades:QualifyingProperties>
3) And again, the debugger shows this element during VERIFICATION
(presuming canonicalization) that is excessive, but at least makes
some sense (though there are no default elements nor 'dsig'
elements). It's added all three namespaces: our default namespace,
the 'dsig' namespace AND the 'xades' namespace.
<xades:QualifyingProperties
*xmlns="http://open.esignforms.com/XMLSchema/2011"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:xades="http://uri.etsi.org/01903/v1.4.1#"*
Id="QualifyingProperties_ID" Target="#OpenESignForms_Seal">
<xades:SignedProperties>
<xades:SignedSignatureProperties>
<xades:SigningTime>2019-02-15T11:30:44-08:00</xades:SigningTime>
</xades:SignedSignatureProperties>
<xades:SignedDataObjectProperties>
<xades:DataObjectFormat
ObjectReference="#Payload_Reference_ID">
<xades:Description>description</xades:Description>
<xades:MimeType>text/html</xades:MimeType>
</xades:DataObjectFormat>
</xades:SignedDataObjectProperties>
</xades:SignedProperties>
</xades:QualifyingProperties
So the libraries are oddly creating two distinct canonicalized XML
for digesting, with the signing phase seeming to miss the important
'xades' namespace declaration entirely. This is no doubt why this is
the only Reference that fails verification as the two. I'm guessing
that the verification digest is correct when using multiple
namespaced objects/references, but the signing digest is not since it
doesn't include the 'xades' namespace declaration.
This seems to hold true for Java 8, 10 and 11. That is, by
specifying null namespaces on atrributes, the code fails the same
under under Java 11, and the debugging output shows the same odd
namespaces above. If I use a single namespace, then it signs fine
under Java 8, 10 and 11.
David
On 2/15/19 11:12 AM, Sean Mullan wrote:
On 2/14/19 9:32 PM, Open eSignForms wrote:
Yes, indeed that's the issue. But I don't know why/how all those
xmlns attributes are added, since I don't directly add them.
I found the only way I can make it work under Java 8, 10 and 11 is
to use my common namespace (XML_NAMESPACE_2011 =
"http://open.esignforms.com/XMLSchema/2011") for all the XADES
elements with the null namespace on all their attributes. Even if
I put that same namespace on the attributes, it then fails.
When I do that, the signed XML generates clean looking XML like this:
<ds:Object>
<QualifyingProperties Id="QualifyingProperties_ID"
Target="#OpenESignForms_Seal">
<SignedProperties><SignedSignatureProperties>
<SigningTime>2019-02-14T17:37:39-08:00</SigningTime>
</SignedSignatureProperties>
<SignedDataObjectProperties>
<DataObjectFormat
ObjectReference="#Payload_Reference_ID">
<Description>description</Description>
<MimeType>text/html</MimeType>
</DataObjectFormat>
</SignedDataObjectProperties>
</SignedProperties>
</QualifyingProperties>
</ds:Object>
<ds:Object>
<ds:SignatureProperties>
<ds:SignatureProperty*Id="OpenESignForms_Seal_ID"
Target="#OpenESignForms_Seal"*>
<OpenESignForms_XmlDigitalSignatureSeal
DeploymentHostAddress="192.1.1.1"
DeploymentHostName="open.esignforms.com" DeploymentId="1.1.1.1"
SignerAddress="192.1.1.1" SignerAgent="No-Browser-Test"
Timestamp="2019-02-14T17:37:39-08:00" Version="19.1.19"/>
</ds:SignatureProperty>
</ds:SignatureProperties>
</ds:Object>
But even above, as you can see, the second ds:Object shows
ds:SignatureProperty, yet the Id and Target attributes do not
include a 'ds:' prefix, which it's my understanding to mean that
they default to our XML payload's default namespace.
I don't think that's correct, I think attributes w/o a prefix by
default belong to the namespace of the element in which they are
defined, which in this case is SignatureProperties and the dsig
namespace.
Regarding below, I would forget about JDK 11 for the time being and
focus on generating a signature with proper XMLNS definitions on JDK
10. If you have any problems verifying with that on JDK 10 or prior,
let me know. The reason is that we will likely be restoring JDK 11
(and later) to the same state it was in for JDK 10. There were some
changes to the marshalling code in JDK 11 which is causing these and
other problems which will likely be backed out.
--Sean