Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect location of ds:Signature after signature, causes validation to fail #87

Open
adamdecaf opened this issue Jan 25, 2023 · 0 comments

Comments

@adamdecaf
Copy link
Contributor

adamdecaf commented Jan 25, 2023

I am using github.com/russellhaering/goxmldsig v1.2.0

I have the following Go structs that represent a document being signed, however the signature is nested inside of the header (AppHdr) struct.

type Request struct {
	XMLName xml.Name   `xml:"Message"`
	Attrs   []xml.Attr `xml:",attr"`

	Header headreq.AppHdr `xml:"AppHdr"`
	Body   document.Iso20022Message
}

type AppHdr struct {
	XMLName xml.Name   `xml:"AppHdr"`
	Attrs   []xml.Attr `xml:",attr"`

	...
	Sgntr     *Sgntr    `xml:"head:Sgntr,omitempty"`
}

type Sgntr struct {
	Attrs     []xml.Attr `xml:",attr"`
	Signature *sigtypes.Signature
}

We have the following code to sign the document.

	edoc := etree.NewDocument()
	err := edoc.ReadFromBytes(data)

	ctx := dsig.NewDefaultSigningContext(mh.keyStore)
	signed, err := ctx.SignEnveloped(notSigned)
	// ... 
	signedDoc := etree.NewDocument()
	signedDoc.SetRoot(notSigned)
	out, err := signedDoc.WriteToBytes()
	// ... 
	return out, nil

This generates the following xml:

<Message xmlns="urn:tch" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance">
  <AppHdr xmlns:head="urn:iso:std:iso:20022:tech:xsd:head.001.001.01">
  ... (No head:Sgntr element)
  </AppHdr>
  <CreditTransfer>
  ...
  </CreditTransfer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2006/12/xml-c14n11" />
      <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
      <ds:Reference URI="">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <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></ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue></ds:SignatureValue>
    <ds:KeyInfo>
      <ds:X509Data>
        <ds:X509Certificate></ds:X509Certificate>
      </ds:X509Data>
    </ds:KeyInfo>
  </ds:Signature>
</Message>

This is unexpected because I would expect *sigtypes.Signature to stand-in for the Signature when nested inside the object. It should look like the following (which matches the spec I'm following).

<Message xmlns="urn:tch" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance">
  <AppHdr xmlns:head="urn:iso:std:iso:20022:tech:xsd:head.001.001.01">
    ...
    <head:Sgntr>
      <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
          <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2006/12/xml-c14n11" />
          <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
          <ds:Reference URI="">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
              <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>...</ds:DigestValue>
          </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>...</ds:SignatureValue>
        <ds:KeyInfo>
          <ds:X509Data>
            <ds:X509Certificate>...</ds:X509Certificate>
          </ds:X509Data>
        </ds:KeyInfo>
      </ds:Signature>
    </head:Sgntr>
  </AppHdr>
  <CreditTransfer>
  ...
  </CreditTransfer>
</Message>

FWIW I've tried to hack in support for moving ds:Signature after signing, but that seems to fail with my validator (3rd party). I understand that manipulating the XML would invalidate the signature, but was hoping it would work. The goxmlsig library will validate the document with ds:Signature appended on the end, but that fails the spec I'm following.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant