goxmldsig icon indicating copy to clipboard operation
goxmldsig copied to clipboard

Invalid handling of xml namespace

Open markwallsgrove opened this issue 7 years ago • 0 comments

It would seem as if the xml namespace is not being handled correctly. If I create a signature for the following XML example the signature cannot be validated:

<Organization xmlns="http://www.w3.org/2000/xmlns" ID="id1234">
      <OrganizationName xml:lang="en">Your Identities</OrganizationName>
      <OrganizationDisplayName xml:lang="en">Your Identities</OrganizationDisplayName>
      <OrganizationURL xml:lang="en">http://www.example.org/</OrganizationURL>
</Organization>
▶ ~/workspace/xmlsectool/xmlsectool-2.0.0/xmlsectool.sh --verifySignature --certificate saml.crt --inFile test.xml
INFO  XMLSecTool - Reading XML document from file 'test.xml'
INFO  XMLSecTool - XML document parsed and is well-formed.
WARN  Reference - Verification failed for URI "#id1234"
WARN  Reference - Expected Digest: 7G4WNjtqxoFobBdFzQtblVRj6oAFVVA/9Jac8HOioAI=
WARN  Reference - Actual Digest: nisb5vb0nPW3Ajd6bkypeJ0QZIEC5VZ2cALuW4lUqYg=
ERROR XMLSecTool - XML document signature verification failed

Whereas the following XML can be verified:

<Organization xmlns="http://www.w3.org/2000/xmlns" ID="id1234">
      <OrganizationName>Your Identities</OrganizationName>
      <OrganizationDisplayName>Your Identities</OrganizationDisplayName>
      <OrganizationURL>http://www.example.org/</OrganizationURL>
</Organization>
▶ ~/workspace/xmlsectool/xmlsectool-2.0.0/xmlsectool.sh --verifySignature --certificate saml.crt --inFile test.xml
INFO  XMLSecTool - Reading XML document from file 'test.xml'
INFO  XMLSecTool - XML document parsed and is well-formed.
INFO  XMLSecTool - XML document signature verified.

Below is the minimum amount of code to demonstrate the issue:

package main

import (
	"crypto/tls"
	"fmt"
	"log"

	"github.com/beevik/etree"
	"github.com/russellhaering/goxmldsig"
)

func failOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
	}
}

func main() {
	certBytes := []byte(`-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIJAKMxnSbqmztEMA0GCSqGSIb3DQEBCwUAMIGEMQswCQYD
VQQGEwJHQjETMBEGA1UECAwKQmlybWluZ2hhbTETMBEGA1UEBwwKQmlybWluZ2hh
bTEOMAwGA1UECgwFVGFsaXMxDjAMBgNVBAsMBVRhbGlzMQ4wDAYDVQQDDAVUYWxp
czEbMBkGCSqGSIb3DQEJARYMbXdAdGFsaXMuY29tMB4XDTE3MDgwODIxNTA0NFoX
DTI3MDgwNjIxNTA0NFowgYQxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApCaXJtaW5n
aGFtMRMwEQYDVQQHDApCaXJtaW5naGFtMQ4wDAYDVQQKDAVUYWxpczEOMAwGA1UE
CwwFVGFsaXMxDjAMBgNVBAMMBVRhbGlzMRswGQYJKoZIhvcNAQkBFgxtd0B0YWxp
cy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfyQiwTxAbc6HJ
6aB6NrmDYoVUBqWZ4njZyQqnhf0ZvpqGh8ppMiXjiuJjn72pJYHnOqRQNgJDNhAZ
X5KtJ/YI4XbOruJU3TWX/KnGn7l8TJ5FFmnJWHohJ0f9/+uVv0hivRkSVUwh+q2e
TpKNypNu2Kf8iiGW3dMOY1CYWxWnksM1xoaWKV3mWgMqRqcj4kyLT1t8UctOhKhg
m04HPNTeFCkcmH3IuIiVAi3uVU+zDKec8+cxSHHmnm0iphm8jpT0OjNSGWt7F7+N
NhIa2FOI+Lz6t+VU0WToWnB16qJIhMGcIGPZR7fp/di/0h9Huc+GJBNfbgdVEYiv
7DuF28zzAgMBAAGjUDBOMB0GA1UdDgQWBBRjnMEGZsZR+cSX5/UJcwAZULsKijAf
BgNVHSMEGDAWgBRjnMEGZsZR+cSX5/UJcwAZULsKijAMBgNVHRMEBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4IBAQBNrPOgLt1bZPO8283HddeASfzoVK40qqBP0HgLihja
VvABPRkE2046lka6MSDXJTpbg9rMT/JDplWea4gCroD+UX79W/r2WBEHgJ63piq+
wVFoxB4S8IgbQi2N5CEM/yLexWq9O2YDl7gemRc1EES01x64YBlBgHGpMvc6NyjD
ecMdTmUAXgNTTGKlpistVRtArQHaqw3FJE3LfoyEx9fP0joA7Q5U7Z6pvveYXEHl
fSoCeI4UUPOlAGBOR5VWnDYuS+FwB9RIcegycxB12Sd+RLxojpFg6VSk2SSiG9/4
u02uKxgXiZ7/41lHjoTHS9BOoPOT0ZD8C7Goeg8OAMgs
-----END CERTIFICATE-----`)

	keyBytes := []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAn8kIsE8QG3Ohyemgeja5g2KFVAalmeJ42ckKp4X9Gb6ahofK
aTIl44riY5+9qSWB5zqkUDYCQzYQGV+SrSf2COF2zq7iVN01l/ypxp+5fEyeRRZp
yVh6ISdH/f/rlb9IYr0ZElVMIfqtnk6SjcqTbtin/Iohlt3TDmNQmFsVp5LDNcaG
lild5loDKkanI+JMi09bfFHLToSoYJtOBzzU3hQpHJh9yLiIlQIt7lVPswynnPPn
MUhx5p5tIqYZvI6U9DozUhlrexe/jTYSGthTiPi8+rflVNFk6FpwdeqiSITBnCBj
2Ue36f3Yv9IfR7nPhiQTX24HVRGIr+w7hdvM8wIDAQABAoIBADrEjdWKvrnaBZ9l
tgg9KG4SRkdpSm8WxKwVLT4AId7eI6dnOiMGtrjB1BIgJnmXufd5sgVuV9awg6tR
Y3kcQXlys2fBGq1rztJfs3HCPU5iP7PZUn8jc4fOEsRw5AznlY/7TMVZae71a/XV
oEFWSHN0bBSOGVyLqZyZGoNuvMAsvZ7ObmfAddLQerPV0nOvv9X332wgo2a+8rnb
NHqcZOLdmGjJRkBbAd0IHFciynb1YlhHIEObmZzD8LVFV0UxhhPDHbRwmrj1T2+j
u9U3rBduJKG+mQxelLOLUB6CNbvcyNtj3wAnyq6IVA9qb/CLXJbEhTgnvNTLnYA3
FJxZysECgYEAzw67MVhQY1VZnN49NiXhhl6ypVIlp3fKOUMMZVgiUeSDPSs4Un9q
ABoFBHT9x/Rs6repl/Yr6V3o8uWz/7V7yArom9/yhErunW8bORfiGVUqibYIKi51
qNJMpamQGI/Uw2AbKCjKhpnCcRjt0YTfuTWXxAxOPYNJZqXEvUaUoNUCgYEAxY3P
H07aR2zTDfjvddG2eieaMLoaTWSuGTUH1P7KplQHEsoE135PyLayzYy5I2HX+JDn
fUDDWXWeI4+NdGdUnRrXOedr/Rewu8RZFxxqBV0TJhmTJzGpoun08YXkj7CBCs60
faohJS5iSpi39XNf2k5/RJHGm2FePfPYQR7sWqcCgYEAx6LYcZdIyr18DXdpZU/Y
xgmADU3K6FDjNZqj1QLI9FRzBQMq5r/aoAZ2V/nExomwig5TAiVj6TmWZLt8dUux
8QozhDbESTFGJ5z8jmusn+gxf113OdRZtVAufnuiZ0wmQ8nh5TKPMoAFra3vfley
rYwyq9+BgGWY29NwgV4P55ECgYB5ThRqkw6xYP9PyxWu8PDtnTeux/eyoinNTKTc
gv+Ilnwpa2cBs4vmIVk1oj1knoXxGXkrjgLmAbTy/QjM+04Xkg2qfpHuvQdGpNBX
wpjPZlGFyZp0LKiPYr2HOMIaATWbn0VxDHCB1jOAvrnmu8uVzzGStziO3IDz5bFa
e1SCbQKBgGNUKKppH7BYDMrb+dqRsB6YI5mFlHZoDhVWkPgDba8klp/NvhTI8ACu
URVaPLlgTRdiG2Q5NVDYPpTrhsCbKwE6HeshNKqhL/VsrK77/oSpSQHeLf88oBV2
rDFpN/In31Wp6c+C4crPQNSWZ9jMohHQkCFOUAyBc6UzcqCa4vqd
-----END RSA PRIVATE KEY-----`)

	xmlBytes := []byte(`<Organization xmlns="http://www.w3.org/2000/xmlns">
	<OrganizationName xml:lang="en">Your Identities</OrganizationName>
	<OrganizationDisplayName xml:lang="en">Your Identities</OrganizationDisplayName>
	<OrganizationURL xml:lang="en">http://www.example.org/</OrganizationURL>
	</Organization>`)

	// xmlBytes := []byte(`<Organization xmlns="http://www.w3.org/2000/xmlns">
	// <OrganizationName>Your Identities</OrganizationName>
	// <OrganizationDisplayName>Your Identities</OrganizationDisplayName>
	// <OrganizationURL>http://www.example.org/</OrganizationURL>
	// </Organization>`)

	keyPair, err := tls.X509KeyPair(certBytes, keyBytes)
	failOnError(err, "invalided to load keypair")

	keyStore := dsig.TLSCertKeyStore(keyPair)

	signingContext := dsig.NewDefaultSigningContext(keyStore)
	signingContext.Canonicalizer = dsig.MakeC14N10ExclusiveCanonicalizerWithPrefixList("")
	err = signingContext.SetSignatureMethod(dsig.RSASHA256SignatureMethod)
	failOnError(err, "failed to set signature method")

	readXMLDoc := etree.NewDocument()
	err = readXMLDoc.ReadFromBytes(xmlBytes)
	failOnError(err, "cannot parse xml")

	elementToSign := readXMLDoc.Root()
	elementToSign.CreateAttr("ID", "id1234")

	signedElement, err := signingContext.SignEnveloped(elementToSign)
	failOnError(err, "failed to sign envelop")

	var signedAssertionBuf []byte
	readXMLDoc.SetRoot(signedElement)
	signedAssertionBuf, err = readXMLDoc.WriteToBytes()
	failOnError(err, "failed to convert doc to bytes")

	fmt.Println(string(signedAssertionBuf))
}

markwallsgrove avatar Aug 20 '17 09:08 markwallsgrove