Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions canonicalization.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func (c *c14N10RecCanonicalizer) ProcessDocument(doc *etree.Document, transformX

func (c c14N10RecCanonicalizer) Process(inputXML string, transformXML string) (outputXML string, err error) {
doc := etree.NewDocument()
doc.ReadSettings.PreserveCData = true
err = doc.ReadFromString(inputXML)
if err != nil {
return "", err
Expand Down Expand Up @@ -73,6 +74,7 @@ func (c *c14N11Canonicalizer) ProcessDocument(doc *etree.Document, transformXML

func (c c14N11Canonicalizer) Process(inputXML string, transformXML string) (outputXML string, err error) {
doc := etree.NewDocument()
doc.ReadSettings.PreserveCData = true
err = doc.ReadFromString(inputXML)
if err != nil {
return "", err
Expand Down
1 change: 1 addition & 0 deletions envelopedsignature.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func (e EnvelopedSignature) ProcessDocument(doc *etree.Document,
// see CanonicalizationAlgorithm.Process
func (e EnvelopedSignature) Process(inputXML string, transformXML string) (outputXML string, err error) {
doc := etree.NewDocument()
doc.ReadSettings.PreserveCData = true
err = doc.ReadFromString(inputXML)
if err != nil {
return "", err
Expand Down
10 changes: 10 additions & 0 deletions exclusivecanonicalization.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func (e ExclusiveCanonicalization) ProcessDocument(doc *etree.Document,
// see CanonicalizationAlgorithm.Process
func (e ExclusiveCanonicalization) Process(inputXML string, transformXML string) (outputXML string, err error) {
doc := etree.NewDocument()
doc.ReadSettings.PreserveCData = true
err = doc.ReadFromString(inputXML)
if err != nil {
return "", err
Expand All @@ -91,6 +92,7 @@ func (e ExclusiveCanonicalization) processDocument(doc *etree.Document, transfor
func (e *ExclusiveCanonicalization) loadPrefixList(transformXML string) {
if transformXML != "" {
tDoc := etree.NewDocument()
tDoc.ReadSettings.PreserveCData = true
tDoc.ReadFromString(transformXML)
inclNSNode := tDoc.Root().SelectElement("InclusiveNamespaces")
if inclNSNode != nil {
Expand Down Expand Up @@ -173,6 +175,14 @@ func (e ExclusiveCanonicalization) processRecursive(node *etree.Element,
removeTokenFromElement(etree.Token(child), node)
i--
}
case *etree.CharData:
// Convert CDATA sections to regular text nodes for canonicalization
// CDATA sections must be converted to escaped text per XML canonicalization rules
if child.IsCData() {
// Replace CDATA with regular text node containing the same data
textNode := etree.NewText(child.Data)
node.Child[i] = textNode
}
case *etree.Element:
e.processRecursive(child, newPrefixesInScope, newDefaultNS)
}
Expand Down
4 changes: 3 additions & 1 deletion signedxml.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ type signatureData struct {
// that Validator will verify
func (s *signatureData) SetSignature(sig string) error {
doc := etree.NewDocument()
doc.ReadSettings.PreserveCData = true
err := doc.ReadFromString(sig)
s.signature = doc.Root()
return err
Expand Down Expand Up @@ -340,6 +341,7 @@ func processTransform(transform *etree.Element,
}

docOut = etree.NewDocument()
docOut.ReadSettings.PreserveCData = true
docOut.ReadFromString(docString)
} else {
docOut = docIn
Expand Down Expand Up @@ -402,11 +404,11 @@ func removeXMLDeclaration(doc *etree.Document) {
// parseXML parses an XML string into an etree.Document and removes the XML declaration if present.
func parseXML(xml string) (*etree.Document, error) {
doc := etree.NewDocument()
doc.ReadSettings.PreserveCData = true
if err := doc.ReadFromString(xml); err != nil {
return nil, err
}

doc.ReadSettings.PreserveCData = true
removeXMLDeclaration(doc)

return doc, nil
Expand Down
30 changes: 30 additions & 0 deletions signedxml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,36 @@ func TestSign(t *testing.T) {
So(err, ShouldBeNil)
So(len(refs), ShouldEqual, 1)
})

Convey("Given an XML with nested XML in CDATA section, certificate, and RSA key", t, func() {
xml, _ := os.ReadFile("./testdata/nosignature-cdata.xml")

Convey("When generating the signature", func() {
signer, _ := NewSigner(string(xml))
xmlStr, err := signer.Sign(key)
Convey("Then no error occurs", func() {
So(err, ShouldBeNil)
})
Convey("And the signature should be valid", func() {
validator, _ := NewValidator(xmlStr)
validator.Certificates = append(validator.Certificates, *cert)
refs, err := validator.ValidateReferences()
So(err, ShouldBeNil)
So(len(refs), ShouldEqual, 1)
})
Convey("And the CDATA section should be preserved in the signed document", func() {
doc := etree.NewDocument()
err := doc.ReadFromString(xmlStr)
So(err, ShouldBeNil)
nestedData := doc.FindElement("//NestedData")
So(nestedData, ShouldNotBeNil)
// Check that CDATA content is preserved
text := nestedData.Text()
So(text, ShouldContainSubstring, "<nested>")
So(text, ShouldContainSubstring, "<item id=\"1\">First Item</item>")
})
})
})
}

func TestValidate(t *testing.T) {
Expand Down
32 changes: 32 additions & 0 deletions testdata/nosignature-cdata.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Document>
<Metadata>
<Title>Test Document</Title>
<Description>This document contains nested XML in CDATA</Description>
</Metadata>
<Content>
<NestedData><![CDATA[<nested>
<item id="1">First Item</item>
<item id="2">Second Item</item>
<item id="3">Third Item</item>
</nested>]]></NestedData>
</Content>
<Footer>
<Author>Test Author</Author>
</Footer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<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></DigestValue>
</Reference>
</SignedInfo>
<SignatureValue />
<KeyInfo>
</KeyInfo>
</Signature>
</Document>
1 change: 1 addition & 0 deletions validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func (v *Validator) SetReferenceIDAttribute(refIDAttribute string) {
// SetXML is used to assign the XML document that the Validator will verify
func (v *Validator) SetXML(xml string) error {
doc := etree.NewDocument()
doc.ReadSettings.PreserveCData = true
err := doc.ReadFromString(xml)
v.xml = doc
return err
Expand Down
Loading