From 70435ab7f818c4bf3f0d0639efbe879e5e8cbb4f Mon Sep 17 00:00:00 2001 From: Phu Kieu Date: Thu, 8 Dec 2016 16:11:17 -0800 Subject: [PATCH] Use signedxml to validate signatures --- Makefile | 1 + xmlsec.go | 38 +++++++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 5469518..db346e2 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ init: go get github.com/nu7hatch/gouuid go get github.com/kardianos/osext go get github.com/stretchr/testify/assert + go get github.com/ma314smith/signedxml vet: init @echo "$(OK_COLOR)==> Go Vetting$(NO_COLOR)" diff --git a/xmlsec.go b/xmlsec.go index 484a940..e0f0400 100644 --- a/xmlsec.go +++ b/xmlsec.go @@ -1,11 +1,16 @@ package saml import ( + "crypto/x509" "errors" "io/ioutil" "os" "os/exec" "strings" + + "encoding/pem" + + "github.com/ma314smith/signedxml" ) const ( @@ -67,31 +72,42 @@ func sign(xml string, privateKeyPath string, id string) (string, error) { // `publicCertPath` must be a path on the filesystem, xmlsec1 is run out of process // through `exec` func VerifyResponseSignature(xml string, publicCertPath string) error { - return verify(xml, publicCertPath, xmlResponseID) + return verify(xml, publicCertPath) } // VerifyRequestSignature verify signature of a SAML 2.0 AuthnRequest document // `publicCertPath` must be a path on the filesystem, xmlsec1 is run out of process // through `exec` func VerifyRequestSignature(xml string, publicCertPath string) error { - return verify(xml, publicCertPath, xmlRequestID) + return verify(xml, publicCertPath) } -func verify(xml string, publicCertPath string, id string) error { - //Write saml to - samlXmlsecInput, err := ioutil.TempFile(os.TempDir(), "tmpgs") +func verify(xml string, publicCertPath string) error { + pemString, err := ioutil.ReadFile(publicCertPath) if err != nil { return err } - samlXmlsecInput.WriteString(xml) - samlXmlsecInput.Close() - defer deleteTempFile(samlXmlsecInput.Name()) + pemBlock, _ := pem.Decode([]byte(pemString)) + if pemBlock == nil { + return errors.New("Could not parse certificate") + } - //fmt.Println("xmlsec1", "--verify", "--pubkey-cert-pem", publicCertPath, "--id-attr:ID", id, samlXmlsecInput.Name()) - _, err = exec.Command("xmlsec1", "--verify", "--pubkey-cert-pem", publicCertPath, "--id-attr:ID", id, samlXmlsecInput.Name()).CombinedOutput() + cert, err := x509.ParseCertificate(pemBlock.Bytes) if err != nil { - return errors.New("error verifing signature: " + err.Error()) + return err + } + + validator, err := signedxml.NewValidator(xml) + if err != nil { + return err + } + + validator.Certificates = append(validator.Certificates, *cert) + + err = validator.Validate() + if err != nil { + return err } return nil }