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: 1 addition & 1 deletion examples/canonicalization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package examples
import (
"testing"

"github.com/moov-io/signedxml"
"github.com/leifj/signedxml"

. "github.com/smartystreets/goconvey/convey"
)
Expand Down
2 changes: 1 addition & 1 deletion examples/examples_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"io"
"os"

"github.com/moov-io/signedxml"
"github.com/leifj/signedxml"
)

func ExampleValidate() {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/moov-io/signedxml
module github.com/leifj/signedxml

go 1.21.0

Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
github.com/beevik/etree v1.5.0 h1:iaQZFSDS+3kYZiGoc9uKeOkUY3nYMXOKLl6KIJxiJWs=
github.com/beevik/etree v1.5.0/go.mod h1:gPNJNaBGVZ9AwsidazFZyygnd+0pAU38N4D+WemwKNs=
github.com/beevik/etree v1.5.1 h1:TC3zyxYp+81wAmbsi8SWUpZCurbxa6S8RITYRSkNRwo=
github.com/beevik/etree v1.5.1/go.mod h1:gPNJNaBGVZ9AwsidazFZyygnd+0pAU38N4D+WemwKNs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down
78 changes: 60 additions & 18 deletions signedxml.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/pem"
"errors"
"fmt"
"log"
"strings"

"github.com/beevik/etree"
Expand Down Expand Up @@ -220,6 +221,38 @@ func (s *signatureData) parseCanonAlgorithm() error {
"CanonicalizationMethod")
}

func findNs(in *etree.Element, ns map[string]string) {
ns[in.Space] = in.NamespaceURI()
for _, c := range in.ChildElements() {
findNs(c, ns)
}
}

func findNamespaces(in *etree.Document) map[string]string {
var ns = make(map[string]string)
findNs(in.Root(), ns)
return ns
}

func fixNs(e *etree.Element, ns map[string]string) {
if e.NamespaceURI() == "" && e.Space != "" {
if uri, ok := ns[e.Space]; ok {
e.CreateAttr(fmt.Sprintf("xmlns:%s", e.Space), uri)
} else {
log.Printf("signedxml: Missing namespace tag %s\n", e.Space)
}
}

for _, c := range e.ChildElements() {
fixNs(c, ns)
}
}

func fixNamespaces(in *etree.Document, out *etree.Document) {
ns := findNamespaces(in)
fixNs(out.Root(), ns)
}

func (s *signatureData) getReferencedXML(reference *etree.Element, inputDoc *etree.Document) (outputDoc *etree.Document, err error) {
uri := reference.SelectAttrValue("URI", "")
uri = strings.Replace(uri, "#", "", 1)
Expand Down Expand Up @@ -251,6 +284,8 @@ func (s *signatureData) getReferencedXML(reference *etree.Element, inputDoc *etr
return nil, errors.New("signedxml: unable to find refereced xml")
}

fixNamespaces(inputDoc, outputDoc)

return outputDoc, nil
}

Expand All @@ -270,39 +305,46 @@ func getCertFromPEMString(pemString string) (*x509.Certificate, error) {
return cert, err
}

const ALL_TRANSFORMS string = ""

func processTransform(transform *etree.Element,
docIn *etree.Document) (docOut *etree.Document, err error) {
docIn *etree.Document, onlyIfContains string) (docOut *etree.Document, err error) {

transformAlgoURI := transform.SelectAttrValue("Algorithm", "")
if transformAlgoURI == "" {
return nil, errors.New("signedxml: unable to find Algorithm in Transform")
}

transformAlgo, ok := CanonicalizationAlgorithms[transformAlgoURI]
if !ok {
return nil, fmt.Errorf("signedxml: unable to find matching transform"+
"algorithm for %s in CanonicalizationAlgorithms", transformAlgoURI)
}
if onlyIfContains == "" || strings.Contains(transformAlgoURI, onlyIfContains) {

transformAlgo, ok := CanonicalizationAlgorithms[transformAlgoURI]
if !ok {
return nil, fmt.Errorf("signedxml: unable to find matching transform"+
"algorithm for %s in CanonicalizationAlgorithms", transformAlgoURI)
}

var transformContent string

var transformContent string
if transform.ChildElements() != nil {
tDoc := etree.NewDocument()
tDoc.SetRoot(transform.Copy())
transformContent, err = tDoc.WriteToString()
if err != nil {
return nil, err
}
}

if transform.ChildElements() != nil {
tDoc := etree.NewDocument()
tDoc.SetRoot(transform.Copy())
transformContent, err = tDoc.WriteToString()
docString, err := transformAlgo.ProcessDocument(docIn, transformContent)
if err != nil {
return nil, err
}
}

docString, err := transformAlgo.ProcessDocument(docIn, transformContent)
if err != nil {
return nil, err
docOut = etree.NewDocument()
docOut.ReadFromString(docString)
} else {
docOut = docIn
}

docOut = etree.NewDocument()
docOut.ReadFromString(docString)

return docOut, nil
}

Expand Down
11 changes: 8 additions & 3 deletions signedxml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ func TestSign(t *testing.T) {
So(len(refs), ShouldEqual, 1)
})
Convey("And the signature should be valid, but validation fail if referenceIDAttribute NOT SET", func() {
validator, _ := NewValidator(xmlStr)
validator, err := NewValidator(xmlStr)
So(err, ShouldBeNil)
So(validator, ShouldNotBeNil)
validator.Certificates = append(validator.Certificates, *cert)
refs, err := validator.ValidateReferences()
So(err, ShouldNotBeNil)
Expand Down Expand Up @@ -157,9 +159,12 @@ func TestSign(t *testing.T) {
signer, _ := NewSigner(string(xml))
signer.SetReferenceIDAttribute("Id")
xmlStr, err := signer.Sign(key)
t.Logf("%#v", xmlStr)
So(err, ShouldBeNil)
So(xmlStr, ShouldNotBeNil)

validator, _ := NewValidator(xmlStr)
validator, err := NewValidator(xmlStr)
So(err, ShouldBeNil)
validator.SetReferenceIDAttribute("Id")
validator.Certificates = append(validator.Certificates, *cert)
refs, err := validator.ValidateReferences()
Expand Down Expand Up @@ -249,7 +254,7 @@ func TestValidate(t *testing.T) {
refs, err := validator.ValidateReferences()
Convey("Then an error occurs", func() {
So(err, ShouldNotBeNil)
So(err.Error(), ShouldContainSubstring, "signedxml:")
So(err.Error(), ShouldContainSubstring, "signedxml")
t.Logf("%v - %d", description, len(refs))
So(len(refs), ShouldEqual, 0)
})
Expand Down
2 changes: 1 addition & 1 deletion signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (s *Signer) setDigest() (err error) {
transforms := ref.SelectElement("Transforms")
if transforms != nil {
for _, transform := range transforms.SelectElements("Transform") {
doc, err = processTransform(transform, doc)
doc, err = processTransform(transform, doc, ALL_TRANSFORMS)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions tests/issue55_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"path/filepath"
"testing"

"github.com/moov-io/signedxml"
"github.com/leifj/signedxml"

"github.com/stretchr/testify/require"
)
Expand All @@ -30,6 +30,6 @@ func TestIssue55(t *testing.T) {
validator.Certificates = append(validator.Certificates, *cert)

refs, err := validator.ValidateReferences()
require.Contains(t, err.Error(), "signedxml: Calculated digest does not match the expected digestvalue of")
require.Contains(t, err.Error(), "does not match the expected digestvalue of")
require.Len(t, refs, 0)
}
19 changes: 14 additions & 5 deletions validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,34 +111,43 @@ func (v *Validator) validateReferences() (referenced []*etree.Document, err erro
transforms := ref.SelectElement("Transforms")
if transforms != nil {
for _, transform := range transforms.SelectElements("Transform") {
doc, err = processTransform(transform, doc)
doc, err = processTransform(transform, doc, ALL_TRANSFORMS)
if err != nil {
return nil, err
}
}
}

refUri := ref.SelectAttrValue("URI", "")
doc, err = v.getReferencedXML(ref, doc)
if err != nil {
return nil, err
}

if transforms != nil {
for _, transform := range transforms.SelectElements("Transform") {
doc, err = processTransform(transform, doc, "c14n")
if err != nil {
return nil, err
}
}
}

referenced = append(referenced, doc)

digestValueElement := ref.SelectElement("DigestValue")
if digestValueElement == nil {
return nil, errors.New("signedxml: unable to find DigestValue")
return nil, fmt.Errorf("signedxml [%s]: unable to find DigestValue", refUri)
}
digestValue := digestValueElement.Text()

calculatedValue, err := calculateHash(ref, doc)
if err != nil {
return nil, err
}

if calculatedValue != digestValue {
return nil, fmt.Errorf("signedxml: Calculated digest does not match the"+
" expected digestvalue of %s", digestValue)
return nil, fmt.Errorf("signedxml [%s]: Calculated digest (%s) does not match the"+
" expected digestvalue of %s", refUri, calculatedValue, digestValue)
}
}
return referenced, nil
Expand Down
Loading