XML-Security / signxml

Python XML Signature and XAdES library
https://xml-security.github.io/signxml/
Apache License 2.0
137 stars 107 forks source link

Document with a signature both enveloped and enveloping fails validation #125

Closed jhominal closed 5 years ago

jhominal commented 5 years ago

I am trying to validate the following document:

https://ec.europa.eu/information_society/policy/esignature/trusted-list/tl-mp.xml

If you look at the document content, you will see that it has the following Signed Information:

<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
  <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
  <ds:Reference Id="xml_ref_id" Type="" URI="">
    <ds:Transforms>
      <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
      <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
    <ds:DigestValue>QNpy4y29ZrofYw8+3w5KWGIs600ShwliDMASqTmwBl4=</ds:DigestValue>
  </ds:Reference>
  <ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xades-id-7881ca95cf9ee505158353417687039e">
    <ds:Transforms>
      <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
    <ds:DigestValue>VtW6B1Ppb5O3adxHzxuTfUMS161G2gq2ebXdLZDogMQ=</ds:DigestValue>
  </ds:Reference>
</ds:SignedInfo>

In other words, for the first reference, the signature is enveloped, and for the second, the signature is enveloping.

In the 2.6.0 implementation of XMLVerifier.verify, I cannot validate this document, because the following sequence happens:

  1. XMLVerifier deserializes the document to variable root and extracts the signature to variable signature_ref;
  2. XMLVerifier.verify processes the first reference and calls the XMLVerifier._apply_transforms method, and because transformation algorithm http://www.w3.org/2000/09/xmldsig#enveloped-signature is being used, the function _remove_sig is called, which has the effect of detaching signature_ref from root;
  3. XMLVerifier.verify then processes the second reference, and tries to locate the element with URI #xades-id-7881ca95cf9ee505158353417687039e in root - however, because the signature has been detached from root, and the element with that ID is enveloped by the signature, the _resolve_references method cannot find the referenced element, and fails;

I would solve the issue in the following way: in the loop that processes the references, instead of operating on root and signature_ref directly, the handling would be done on a copy of the root variable, and signature_ref would be re-resolved from the copy of root.

Please do not hesitate in giving your feedback, if you have any issues. Otherwise, I will try to make a PR implementing the solution above in the coming days.

kislyuk commented 5 years ago

Thank you for the thorough explanation of the issue you are facing and the PR. I left a comment in #126. Sorry about the delay in reviewing this.