Skip to content

Commit

Permalink
fix: support Signature element on the root level
Browse files Browse the repository at this point in the history
Issue: #46
Issue: #47
  • Loading branch information
adamdecaf committed Feb 19, 2024
1 parent 2438076 commit 130303b
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 17 deletions.
17 changes: 13 additions & 4 deletions envelopedsignature.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package signedxml

import (
"errors"
"strings"

"github.com/beevik/etree"
)
Expand Down Expand Up @@ -57,15 +58,23 @@ func (e EnvelopedSignature) Process(inputXML string, transformXML string) (outpu
}

func (e EnvelopedSignature) processElement(inputXML *etree.Element, transformXML string) (outputXML *etree.Element, err error) {
sig := inputXML.FindElement(".//Signature")
sig := inputXML.FindElement("//Signature")
if sig == nil {
// TODO(adam): Why can't ./Signature (or /Signature, or //Signature) find the root Signature element?
if strings.EqualFold(inputXML.Tag, "Signature") {
sig = inputXML
}
}
if sig == nil {
return nil, errors.New("signedxml: unable to find Signature node")
}

sigParent := sig.Parent()
elem := sigParent.RemoveChild(sig)
if elem == nil {
return nil, errors.New("signedxml: unable to remove Signature element")
if sigParent != nil {
elem := sigParent.RemoveChild(sig)
if elem == nil {
return nil, errors.New("signedxml: unable to remove Signature element")
}
}

return inputXML, nil
Expand Down
2 changes: 1 addition & 1 deletion signedxml.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (s *signatureData) SetSignature(sig string) error {
}

func (s *signatureData) parseEnvelopedSignature() error {
sig := s.xml.FindElement(".//Signature")
sig := s.xml.FindElement("//Signature")
if sig != nil {
s.signature = sig
} else {
Expand Down
33 changes: 21 additions & 12 deletions signedxml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"testing"

"github.com/beevik/etree"
Expand Down Expand Up @@ -98,6 +99,26 @@ func TestSign(t *testing.T) {

})

Convey("Signature at the Root level, surrounding the Object", t, func() {
xml, _ := os.ReadFile(filepath.Join("testdata", "root-level-signature.xml"))

doc := etree.NewDocument()
doc.ReadFromBytes(xml)
signature := doc.FindElement("//Signature")
t.Logf("signature: %#v", signature)

signer, _ := NewSigner(string(xml))
signer.SetReferenceIDAttribute("Id")
xmlStr, err := signer.Sign(key)
So(err, ShouldBeNil)

validator, _ := NewValidator(xmlStr)
validator.SetReferenceIDAttribute("Id")
validator.Certificates = append(validator.Certificates, *cert)
refs, err := validator.ValidateReferences()
So(err, ShouldBeNil)
So(len(refs), ShouldEqual, 1)
})
}

func TestValidate(t *testing.T) {
Expand Down Expand Up @@ -223,18 +244,6 @@ func TestEnvelopedSignatureProcess(t *testing.T) {
})
})
})

Convey("Given an unparented signature element", t, func() {
doc := "<Signature></Signature>"
Convey("When ProcessDocument is called", func() {
envSig := EnvelopedSignature{}
_, err := envSig.Process(doc, "")
Convey("Then an error occurs", func() {
So(err, ShouldNotBeNil)
So(err.Error(), ShouldContainSubstring, "signedxml:")
})
})
})
}

func TestSignatureDataParsing(t *testing.T) {
Expand Down
23 changes: 23 additions & 0 deletions testdata/root-level-signature.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>
<Reference URI="#test">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
</Transforms>
<DigestValue></DigestValue>
</Reference>
</SignedInfo>
<SignatureValue></SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>testtest</X509Certificate>
</X509Data>
</KeyInfo>
<Object xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Id="test">
<Foo>name</Foo>
</Object>
</Signature>

0 comments on commit 130303b

Please sign in to comment.