forked from lestrrat-go/xmlsec
-
Notifications
You must be signed in to change notification settings - Fork 1
/
verify.go
103 lines (87 loc) · 1.86 KB
/
verify.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package dsig
import (
"github.com/lestrrat-go/libxml2/parser"
"github.com/lestrrat-go/libxml2/xpath"
"github.com/lestrrat-go/xmlsec"
"github.com/lestrrat-go/xmlsec/clib"
"github.com/lestrrat-go/xmlsec/crypto"
)
func NewSignatureVerify() (*SignatureVerify, error) {
return &SignatureVerify{}, nil
}
func (v *SignatureVerify) LoadKeyFromFile(file string, format crypto.KeyDataFormat) error {
k, err := crypto.LoadKeyFromFile(file, format)
if err != nil {
return err
}
if v.key != nil {
v.key.Free()
}
v.key = k
return nil
}
func (v *SignatureVerify) Free() {
if v.key == nil {
return
}
v.key.Free()
}
func (v *SignatureVerify) Verify(buf []byte) error {
p := parser.New(parser.XMLParseDTDLoad | parser.XMLParseDTDAttr | parser.XMLParseNoEnt)
doc, err := p.Parse(buf)
if err != nil {
return err
}
defer doc.Free()
mngr, err := crypto.NewKeyManager()
if err != nil {
return err
}
defer mngr.Free()
ctx, err := NewCtx(mngr)
if err != nil {
return err
}
defer ctx.Free()
root, err := doc.DocumentElement()
if err != nil {
return err
}
signode, err := clib.FindSignatureNode(root)
if err != nil {
return err
}
// Create a key manager, load keys from KeyInfo
prefix, err := signode.LookupNamespacePrefix(xmlsec.DSigNs)
if err != nil {
return err
}
if prefix == "" {
prefix = xmlsec.Prefix
}
xpc, err := xpath.NewContext(signode)
if err != nil {
return err
}
xpc.RegisterNS(prefix, xmlsec.Prefix)
iter := xpath.NodeIter(xpc.Find("//" + prefix + ":KeyInfo"))
for iter.Next() {
n := iter.Node()
if err := mngr.GetKey(n); err != nil {
return err
}
}
if key := v.key; key != nil {
cpy, err := key.Copy()
if err != nil {
return err
}
if err := ctx.SetKey(cpy); err != nil {
return err
}
}
return ctx.Verify(doc)
}
func (v *SignatureVerify) VerifyString(buf string) error {
return v.Verify([]byte(buf))
}