Initial work to sign/verify multiple xml nodes concurrently
This commit is contained in:
24
resources/certs/cert1
Normal file
24
resources/certs/cert1
Normal file
@@ -0,0 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDzzCCAzigAwIBAgIJAK+ii7kzrdqtMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEQMA4G
|
||||
A1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3
|
||||
DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMCAXDTE0MDUyMzE3NTIzOFoYDzIxMTQw
|
||||
NDI5MTc1MjM4WjCBnDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx
|
||||
PTA7BgNVBAoTNFhNTCBTZWN1cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtz
|
||||
ZXkuY29tL3htbHNlYykxFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAfBgkqhkiG
|
||||
9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC
|
||||
QQCyuvKJ2CuUPD33ghPt4Q8MilesHxVbbpyKfmabrYVpDGVDmOKKp337qJUZZ95K
|
||||
fwlXbR2j0zyKWJmvRxUx+PsTAgMBAAGjggFFMIIBQTAMBgNVHRMEBTADAQH/MCwG
|
||||
CWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV
|
||||
HQ4EFgQU/uTsUyTwlZXHELXhRLVdOWVa434wgeMGA1UdIwSB2zCB2IAUBrWkrKeq
|
||||
dUTqFZxP3wWDT2oe/guhgbSkgbEwga4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpD
|
||||
YWxpZm9ybmlhMT0wOwYDVQQKEzRYTUwgU2VjdXJpdHkgTGlicmFyeSAoaHR0cDov
|
||||
L3d3dy5hbGVrc2V5LmNvbS94bWxzZWMpMRAwDgYDVQQLEwdSb290IENBMRYwFAYD
|
||||
VQQDEw1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3Nl
|
||||
eS5jb22CCQCvoou5M63arDANBgkqhkiG9w0BAQUFAAOBgQBuTAW63AgWqqUDPGi8
|
||||
BiXbdKHhFP4J8qgkdv5WMa6SpSWVgNgOYXkK/BSg1aSmQtGv8/8UvBRPoJnO4y0N
|
||||
jWUFf1ubOgUNmedYNLq7YbTp8yTGWeogCyM2xdWELMP8BMgQL0sP+MDAFMKO3itY
|
||||
mEWnCEsP15HKSTms54RNj7oJ+A==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
25
resources/certs/cert2
Normal file
25
resources/certs/cert2
Normal file
@@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID9zCCA2CgAwIBAgIJAK+ii7kzrdqsMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEQMA4G
|
||||
A1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3
|
||||
DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMCAXDTE0MDUyMzE3NTA1OVoYDzIxMTQw
|
||||
NDI5MTc1MDU5WjCBrjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx
|
||||
PTA7BgNVBAoTNFhNTCBTZWN1cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtz
|
||||
ZXkuY29tL3htbHNlYykxEDAOBgNVBAsTB1Jvb3QgQ0ExFjAUBgNVBAMTDUFsZWtz
|
||||
ZXkgU2FuaW4xITAfBgkqhkiG9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTCBnzAN
|
||||
BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtY4MCNj/qrOzVuex1BD/PuCYTDDOLLVj
|
||||
tpKXQteQPqy0kgMwuQgRwdNnICIHQbnFKL40XoyACJVWKM7b0LkvWJNeyVzXPqEE
|
||||
9ZPmNxWGUjVcr7powT7v8V7S2QflUnr8ZvR4XWwkZJ9EYKNhenijgJ5yYDrXCWdv
|
||||
C+fnjBjv2LcCAwEAAaOCARcwggETMB0GA1UdDgQWBBQGtaSsp6p1ROoVnE/fBYNP
|
||||
ah7+CzCB4wYDVR0jBIHbMIHYgBQGtaSsp6p1ROoVnE/fBYNPah7+C6GBtKSBsTCB
|
||||
rjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhN
|
||||
TCBTZWN1cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNl
|
||||
YykxEDAOBgNVBAsTB1Jvb3QgQ0ExFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAf
|
||||
BgkqhkiG9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbYIJAK+ii7kzrdqsMAwGA1Ud
|
||||
EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEARpb86RP/ck55X+NunXeIX81i763b
|
||||
j7Z1VJwFbA/QfupzxnqJ2IP/lxC8YxJ3Bp2IJMI7rC9r0poa41ZxI5rGHip97Dpg
|
||||
sxPF9lkRUmKBBQjkICOq1w/4d2DRInBoqXttD+0WsqDfNDVK+7kSE07ytn3RzHCj
|
||||
j0gv0PdxmuCsR/E=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
23
resources/certs/cert3
Normal file
23
resources/certs/cert3
Normal file
@@ -0,0 +1,23 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
122
xmldsig.go
122
xmldsig.go
@@ -5,12 +5,36 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #include <xmlsec/xmlsec.h>
|
||||
// #include <xmlsec/xmltree.h>
|
||||
// #include <xmlsec/xmlenc.h>
|
||||
// #include <xmlsec/xmldsig.h>
|
||||
// #include <xmlsec/errors.h>
|
||||
// #include <xmlsec/crypto.h>
|
||||
/*
|
||||
#include <xmlsec/xmlsec.h>
|
||||
#include <xmlsec/xmltree.h>
|
||||
#include <xmlsec/xmlenc.h>
|
||||
#include <xmlsec/xmldsig.h>
|
||||
#include <xmlsec/errors.h>
|
||||
#include <xmlsec/crypto.h>
|
||||
#include <xmlsec/nodeset.h>
|
||||
#include <libxml/list.h>
|
||||
|
||||
void
|
||||
xmlSecFindNodes(const xmlListPtr found, const xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) {
|
||||
|
||||
xmlNodePtr cur;
|
||||
xmlNodePtr ret;
|
||||
|
||||
xmlSecAssert2(name != NULL, NULL);
|
||||
|
||||
cur = parent;
|
||||
while(cur != NULL) {
|
||||
if(cur->children != NULL) {
|
||||
xmlSecFindNodes(found, cur->children, name, ns);
|
||||
}
|
||||
if((cur->type == XML_ELEMENT_NODE) && xmlSecCheckNodeName(cur, name, ns)) {
|
||||
xmlListPushFront(found, cur);
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// SignatureOptions represents additional, less commonly used, options for Sign and
|
||||
@@ -42,6 +66,36 @@ func Sign(key []byte, doc []byte, opts SignatureOptions) ([]byte, error) {
|
||||
startProcessingXML()
|
||||
defer stopProcessingXML()
|
||||
|
||||
parsedDoc, err := newDoc(doc, opts.XMLID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer closeDoc(parsedDoc)
|
||||
|
||||
// #nosec
|
||||
found := C.xmlListCreate(nil, nil)
|
||||
defer func() { C.xmlListDelete(found) }()
|
||||
|
||||
C.xmlSecFindNodes(
|
||||
found,
|
||||
C.xmlDocGetRootElement(parsedDoc),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
|
||||
|
||||
c := C.xmlListSize(found)
|
||||
if c == 0 {
|
||||
return nil, errors.New("cannot find start node")
|
||||
}
|
||||
|
||||
for C.xmlListEmpty(found) == 0 {
|
||||
link := C.xmlListFront(found)
|
||||
if link == nil {
|
||||
return nil, errors.New("Link is null")
|
||||
}
|
||||
|
||||
node := (C.xmlNodePtr)(C.xmlLinkGetData(link))
|
||||
if node != nil {
|
||||
|
||||
ctx := C.xmlSecDSigCtxCreate(nil)
|
||||
if ctx == nil {
|
||||
return nil, errors.New("failed to create signature context")
|
||||
@@ -54,27 +108,17 @@ func Sign(key []byte, doc []byte, opts SignatureOptions) ([]byte, error) {
|
||||
C.xmlSecSize(len(key)),
|
||||
C.xmlSecKeyDataFormatPem,
|
||||
nil, nil, nil)
|
||||
|
||||
if ctx.signKey == nil {
|
||||
return nil, errors.New("failed to load pem key")
|
||||
}
|
||||
|
||||
parsedDoc, err := newDoc(doc, opts.XMLID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer closeDoc(parsedDoc)
|
||||
|
||||
// #nosec
|
||||
node := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
|
||||
if node == nil {
|
||||
return nil, errors.New("cannot find start node")
|
||||
}
|
||||
|
||||
if rv := C.xmlSecDSigCtxSign(ctx, node); rv < 0 {
|
||||
return nil, errors.New("failed to sign")
|
||||
}
|
||||
}
|
||||
C.xmlListPopFront(found)
|
||||
}
|
||||
|
||||
return dumpDoc(parsedDoc), nil
|
||||
|
||||
@@ -131,12 +175,6 @@ func Verify(publicKey []byte, doc []byte, opts SignatureOptions) error {
|
||||
return mustPopError()
|
||||
}
|
||||
|
||||
dsigCtx := C.xmlSecDSigCtxCreate(keysMngr)
|
||||
if dsigCtx == nil {
|
||||
return mustPopError()
|
||||
}
|
||||
defer C.xmlSecDSigCtxDestroy(dsigCtx)
|
||||
|
||||
parsedDoc, err := newDoc(doc, opts.XMLID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -144,19 +182,41 @@ func Verify(publicKey []byte, doc []byte, opts SignatureOptions) error {
|
||||
defer closeDoc(parsedDoc)
|
||||
|
||||
// #nosec
|
||||
node := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||
found := C.xmlListCreate(nil, nil)
|
||||
defer func() { C.xmlListDelete(found) }()
|
||||
|
||||
C.xmlSecFindNodes(
|
||||
found,
|
||||
C.xmlDocGetRootElement(parsedDoc),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
|
||||
if node == nil {
|
||||
|
||||
c := C.xmlListSize(found)
|
||||
if c == 0 {
|
||||
return errors.New("cannot find start node")
|
||||
}
|
||||
|
||||
if rv := C.xmlSecDSigCtxVerify(dsigCtx, node); rv < 0 {
|
||||
for C.xmlListEmpty(found) == 0 {
|
||||
link := C.xmlListFront(found)
|
||||
if link == nil {
|
||||
break
|
||||
}
|
||||
node := (C.xmlNodePtr)(C.xmlLinkGetData(link))
|
||||
if node != nil {
|
||||
ctx := C.xmlSecDSigCtxCreate(keysMngr)
|
||||
if ctx == nil {
|
||||
return mustPopError()
|
||||
}
|
||||
defer C.xmlSecDSigCtxDestroy(ctx)
|
||||
|
||||
if rv := C.xmlSecDSigCtxVerify(ctx, node); rv < 0 {
|
||||
return ErrVerificationFailed
|
||||
}
|
||||
|
||||
if dsigCtx.status != xmlSecDSigStatusSucceeded {
|
||||
if ctx.status != xmlSecDSigStatusSucceeded {
|
||||
return ErrVerificationFailed
|
||||
}
|
||||
}
|
||||
C.xmlListPopFront(found)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
204
xmldsig_test.go
204
xmldsig_test.go
@@ -2,9 +2,8 @@ package xmlsec
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"strings"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Envelope struct {
|
||||
@@ -163,6 +162,207 @@ fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
c.Assert(err, IsNil)
|
||||
}
|
||||
|
||||
func (testSuite *XMLDSigTest) TestSignAndVerifyMultiple(c *C) {
|
||||
expectedSignedString := `<?xml version="1.0"?>
|
||||
<Envelope xmlns="urn:envelope">
|
||||
<Data1 ID="id1">
|
||||
Hello, World!
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<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="#id1">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||
<DigestValue>ixa7UpgiS2UJ37IG9HzhfK7z+Fo=</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>xaMgajZ9tBswZmIP5JoBwXMpD9W74fVbfWJ/HkfTHYkXNejOXT+UocvaGaVCqPNE
|
||||
+6rzavcVq18agibmYCkm6w==</SignatureValue>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
<Data2 ID="id2">
|
||||
Hello, World!
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<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="#id2">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||
<DigestValue>6hs7C+iZA45BBGAcaI0aNnMz+Ts=</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>F23IldNw0Gozri5ySU5Esopz7llkBrDJNHNgm+Ww93mrU5w1IrP0J7Cv0Xn19ro2
|
||||
QsO3oBVrpdMotMsFkbEVkA==</SignatureValue>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
</Data2>
|
||||
</Data1>
|
||||
</Envelope>
|
||||
`
|
||||
actualUnsignedString := `
|
||||
<Envelope xmlns="urn:envelope">
|
||||
<Data1 ID="id1">
|
||||
Hello, World!
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<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="#id1">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||
<DigestValue/>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue/>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
<Data2 ID="id2">
|
||||
Hello, World!
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<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="#id2">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||
<DigestValue/>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue/>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
</Data2>
|
||||
</Data1>
|
||||
</Envelope>
|
||||
`
|
||||
opts := SignatureOptions{XMLID: []XMLIDOption{
|
||||
XMLIDOption{ElementName: "Data1", AttributeName: "ID"},
|
||||
XMLIDOption{ElementName: "Data2", AttributeName: "ID"},
|
||||
}}
|
||||
|
||||
actualSignedString, err := Sign(testSuite.Key, []byte(actualUnsignedString), opts)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(string(actualSignedString), Equals, expectedSignedString)
|
||||
|
||||
err = Verify(testSuite.Cert, actualSignedString, opts)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
data1Sig := `<SignatureValue>xaMgajZ9tBswZmIP5JoBwXMpD9W74fVbfWJ/HkfTHYkXNejOXT+UocvaGaVCqPNE
|
||||
+6rzavcVq18agibmYCkm6w==</SignatureValue>`
|
||||
data2Sig := `<SignatureValue>F23IldNw0Gozri5ySU5Esopz7llkBrDJNHNgm+Ww93mrU5w1IrP0J7Cv0Xn19ro2
|
||||
QsO3oBVrpdMotMsFkbEVkA==</SignatureValue>`
|
||||
|
||||
breakData1 := strings.Replace(expectedSignedString, data1Sig, data2Sig, 1)
|
||||
err = Verify(testSuite.Cert, []byte(breakData1), opts)
|
||||
c.Assert(err, ErrorMatches, "signature verification failed")
|
||||
|
||||
breakData2 := strings.Replace(expectedSignedString, data2Sig, data1Sig, 1)
|
||||
err = Verify(testSuite.Cert, []byte(breakData2), opts)
|
||||
c.Assert(err, ErrorMatches, "signature verification failed")
|
||||
}
|
||||
|
||||
func (testSuite *XMLDSigTest) TestConstructFromSignature(c *C) {
|
||||
// Try again but this time construct the message from a struct having a Signature member
|
||||
doc := Envelope{Data: "Hello, World!"}
|
||||
|
||||
Reference in New Issue
Block a user