ZATCA Toolkit SDK Produces Invalid Results for E-invoicing Phase 2

This describes the invalid results produced by the ZATCA Toolkit SDK at https://zatca.gov.sa/en/E-Invoicing/SystemsDevelopers/ComplianceEnablementToolbox/Pages/DownloadSDK.aspx

The ZATCA toolkit produces a DigestValue for the xadesSignedProperties (i.e. 2nd Reference) that is not correct.

For example, the following sha256 digest (created by ZATCA) is NOT correct:

<ds:Reference Type=“http://www.w3.org/2000/09/xmldsig#SignatureProperties” URI=”#xadesSignedProperties”>
<ds:DigestMethod Algorithm=“http://www.w3.org/2001/04/xmlenc#sha256”/>
<ds:DigestValue>ZDZjMzQyZTBjNGVjY2VlODgxYTBiMzhiNDFlM2QxZTlkZDkyMDQ1NTEwNzUwN2RhYjUwNGNmZmNmNTFmY2I2OA==</ds:DigestValue>
</ds:Reference>

The base64 string “ZDZ…..” decodes to 64 bytes.  A SHA256 digest MUST be 32 bytes. 

However, the ZATCA toolkit does produce the correct DigestValue for the 1st Reference, such as shown here.

                            <ds:Reference Id=”invoiceSignedData” URI=””>
<ds:Transforms>
<ds:Transform Algorithm=”http://www.w3.org/TR/1999/REC-xpath-19991116″>
<ds:XPath>not(//ancestor-or-self::ext:UBLExtensions)</ds:XPath>
</ds:Transform>
<ds:Transform Algorithm=”http://www.w3.org/TR/1999/REC-xpath-19991116″>
<ds:XPath>not(//ancestor-or-self::cac:Signature)</ds:XPath>
</ds:Transform>
<ds:Transform Algorithm=”http://www.w3.org/TR/1999/REC-xpath-19991116″>
<ds:XPath>not(//ancestor-or-self::cac:AdditionalDocumentReference[cbc:ID=’QR’])</ds:XPath>
</ds:Transform>
<ds:Transform Algorithm=”http://www.w3.org/2006/12/xml-c14n11″/>
</ds:Transforms>
<ds:DigestMethod Algorithm=”http://www.w3.org/2001/04/xmlenc#sha256″/>
<ds:DigestValue>+bA1mucVI67H4WCbN/e9J2qUpHTt3TwMdxlkOWTeov8=</ds:DigestValue>
</ds:Reference>

Regarding the 2nd Reference, Chilkat believes the ZATCA tool is not correctly following the XMLDSig Standard’s processing model.
See https://www.w3.org/TR/xmldsig-core/#sec-ReferenceProcessingModel

It is not easy to understand, but here are the relevant points for the 2nd Reference (where URI=”#xadesSignedProperties”)

4.4.3.2 The Reference Processing Model


The Transforms specified in this document are defined with respect to the input they require. The following is the default signature application behavior:

  • If the data object is an octet stream and the next transform requires a node-set, the signature application MUST attempt to parse the octets yielding the required node-set via [XML10] well-formed processing.
  • If the data object is a node-set and the next transform requires octets, the signature application MUST attempt to convert the node-set to an octet stream using Canonical XML [XML-C14N].

4.4.3.4 The Transforms Element

The optional Transforms element contains an ordered list of Transform elements; these describe how the signer obtained the data object that was digested. The output of each Transform serves as input to the next Transform. The input to the first Transform is the result of dereferencing the URI attribute of the Reference element. The output from the last Transform is the input for the DigestMethod algorithm.

4.4.3.5 The DigestMethod Element

If the result of the URI dereference and application of Transforms is an XPath node-set (or sufficiently functional replacement implemented by the application) then it must be converted as described in section 4.4.3.2 The Reference Processing Model. If the result of URI dereference and application of transforms is an octet stream, then no conversion occurs (comments might be present if the Canonical XML with Comments was specified in the Transforms). The digest algorithm is applied to the data octets of the resulting octet stream.

Here’s what SHOULD happen with the following reference:

<ds:Reference Type=“http://www.w3.org/2000/09/xmldsig#SignatureProperties” URI=”#xadesSignedProperties”>
<ds:DigestMethod Algorithm=“http://www.w3.org/2001/04/xmlenc#sha256”/>
<ds:DigestValue>….</ds:DigestValue>
</ds:Reference>

The above reference is a Same-Document URI-Reference, and there are no Transforms specified.  Therefore, the act of applying the same-document URI reference results in an XPath node-set, which must be digested using SHA256.  The digest requires an octet stream, and therefore we must convert from XPath node-set to byte stream by applying the standard C14N XML canonicalization (See https://www.w3.org/TR/2001/REC-xml-c14n-20010315).