moov-io / signedxml

pure go library for processing signed XML documents
MIT License
52 stars 44 forks source link

Discrepancy in Signature Validation with XML Declaration Presence. #49

Open call-stack opened 6 months ago

call-stack commented 6 months ago

I've encountered an issue related to the validation of XML signatures generated and verified using specific canonicalization methods. Below is the template of the XML signature being used:

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
            <Reference URI="">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                <DigestValue/>
            </Reference>
        </SignedInfo>
        <SignatureValue/>
        <KeyInfo>
            <KeyValue>
                <RSAKeyValue>
                    <Modulus/>
                    <Exponent/>
                </RSAKeyValue>
            </KeyValue>
        </KeyInfo>

From my understanding, the canonicalization method specified by http://www.w3.org/TR/2001/REC-xml-c14n-20010315 should not include the XML declaration in the canonicalized output. Could you please confirm if this understanding is correct?

If so, I would expect that the XML declaration would be removed during the signature verification process, as it's not part of the canonical form used for computing the digest. However, I've observed that the digest value does not match during verification when the XML declaration is present. Removing the XML declaration manually results in a successful match of the digest value.

Could you clarify if it's intended behavior that the XML declaration must be manually removed before validating the signature? Or is there a potential issue or misunderstanding on my part regarding the canonicalization process and its impact on signature verification?

adamdecaf commented 6 months ago

I'm not super familiar with all the details of c14n algorithms, but signedxml doesn't have complete implementations. I couldn't find a pure-Go implementation to use so we got as far as we could. If you can help out I'll happily review and test. If there is a CGO library that does complete c14n translations I'd be interested in adopting it.

mrigankakb commented 6 months ago

Not sure about what the canonicalization standards actually says. However I would expect the implementation to handle all those details without me having to worry. So that I get a cleaner interface where I can pass the full content of an xml file into the NewValidator. i.e. I expect the below code to work.

    validator, err := signedxml.NewValidator( string( allTheBytesFromAnXmlFile ) )
    if err != nil {
        return fmt.Errorf("error creating validator for %s, %w", filename, err)
    }
    xml, err := validator.ValidateReferences()

IMO, support for xml handling in golang ecosystem is quite immature compared to java. This module is a ray of hope.

adamdecaf commented 5 months ago

Yea. It might be easier to tie into a Java library with JNI than reimplement all of the xml logic.

https://github.com/moov-io/signedxml/issues/46 is another instance of this.

call-stack commented 4 months ago

Thank you for suggesting the use of a Java library via JNI for XML processing. While this remains a viable backup option, I prefer to first explore solutions that keep our work entirely within Go. I will be actively researching and experimenting with native Go libraries to address this issue.

call-stack commented 4 months ago

@adamdecaf can you please review this? https://github.com/moov-io/signedxml/pull/53