fix Sign/Verify to take byte slices not strings
This commit is contained in:
@@ -33,16 +33,16 @@ func main() {
|
|||||||
buf, err := ioutil.ReadAll(os.Stdin)
|
buf, err := ioutil.ReadAll(os.Stdin)
|
||||||
|
|
||||||
if *doSign {
|
if *doSign {
|
||||||
signedBuf, err := xmldsig.Sign(key, string(buf))
|
signedBuf, err := xmldsig.Sign(key, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%s\n", err)
|
fmt.Printf("%s\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
fmt.Print(signedBuf)
|
os.Stdout.Write(signedBuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *doVerify {
|
if *doVerify {
|
||||||
err := xmldsig.Verify(key, string(buf))
|
err := xmldsig.Verify(key, buf)
|
||||||
if err == xmldsig.ErrVerificationFailed {
|
if err == xmldsig.ErrVerificationFailed {
|
||||||
fmt.Println("signature is not correct")
|
fmt.Println("signature is not correct")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
@@ -59,8 +59,9 @@ func closeContext(ctx *C.xmlSecDSigCtx) {
|
|||||||
C.xmlSecDSigCtxDestroy(ctx)
|
C.xmlSecDSigCtxDestroy(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDoc(s string) (*C.xmlDoc, error) {
|
func newDoc(buf []byte) (*C.xmlDoc, error) {
|
||||||
ctx := C.xmlCreateMemoryParserCtxt(C.CString(s), C.int(len(s)))
|
ctx := C.xmlCreateMemoryParserCtxt((*C.char)(unsafe.Pointer(&buf[0])),
|
||||||
|
C.int(len(buf)))
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
return nil, errors.New("error creating parser")
|
return nil, errors.New("error creating parser")
|
||||||
}
|
}
|
||||||
@@ -80,13 +81,16 @@ func newDoc(s string) (*C.xmlDoc, error) {
|
|||||||
return doc, nil
|
return doc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpDoc(doc *C.xmlDoc) string {
|
func dumpDoc(doc *C.xmlDoc) []byte {
|
||||||
var buffer *C.xmlChar
|
var buffer *C.xmlChar
|
||||||
var bufferSize C.int
|
var bufferSize C.int
|
||||||
C.xmlDocDumpMemory(doc, &buffer, &bufferSize)
|
C.xmlDocDumpMemory(doc, &buffer, &bufferSize)
|
||||||
rv := C.GoStringN((*C.char)(unsafe.Pointer(buffer)), bufferSize)
|
rv := C.GoStringN((*C.char)(unsafe.Pointer(buffer)), bufferSize)
|
||||||
C.MY_xmlFree(unsafe.Pointer(buffer))
|
C.MY_xmlFree(unsafe.Pointer(buffer))
|
||||||
return rv
|
|
||||||
|
// TODO(ross): this is totally nasty un-idiomatic, but I'm
|
||||||
|
// tired of googling how to copy a []byte from a char*
|
||||||
|
return []byte(rv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func closeDoc(doc *C.xmlDoc) {
|
func closeDoc(doc *C.xmlDoc) {
|
||||||
@@ -97,31 +101,31 @@ func closeDoc(doc *C.xmlDoc) {
|
|||||||
// the XML-DSIG standard. docStr is a template document meaning
|
// the XML-DSIG standard. docStr is a template document meaning
|
||||||
// that it contains a `Signature` element in the
|
// that it contains a `Signature` element in the
|
||||||
// http://www.w3.org/2000/09/xmldsig# namespace.
|
// http://www.w3.org/2000/09/xmldsig# namespace.
|
||||||
func Sign(key []byte, docStr string) (string, error) {
|
func Sign(key []byte, doc []byte) ([]byte, error) {
|
||||||
ctx, err := newContext(key)
|
ctx, err := newContext(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer closeContext(ctx)
|
defer closeContext(ctx)
|
||||||
|
|
||||||
doc, err := newDoc(docStr)
|
parsedDoc, err := newDoc(doc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer closeDoc(doc)
|
defer closeDoc(parsedDoc)
|
||||||
|
|
||||||
node := C.xmlSecFindNode(C.xmlDocGetRootElement(doc),
|
node := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
|
||||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
|
||||||
if node == nil {
|
if node == nil {
|
||||||
return "", errors.New("cannot find start node")
|
return nil, errors.New("cannot find start node")
|
||||||
}
|
}
|
||||||
|
|
||||||
if rv := C.xmlSecDSigCtxSign(ctx, node); rv < 0 {
|
if rv := C.xmlSecDSigCtxSign(ctx, node); rv < 0 {
|
||||||
return "", errors.New("failed to sign")
|
return nil, errors.New("failed to sign")
|
||||||
}
|
}
|
||||||
|
|
||||||
return dumpDoc(doc), nil
|
return dumpDoc(parsedDoc), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrVerificationFailed is returned from Verify when the signature is incorrect
|
// ErrVerificationFailed is returned from Verify when the signature is incorrect
|
||||||
@@ -137,20 +141,20 @@ const (
|
|||||||
// to the XML-DSIG specification. publicKey is the public part of
|
// to the XML-DSIG specification. publicKey is the public part of
|
||||||
// the key used to sign docStr. If the signature is not correct,
|
// the key used to sign docStr. If the signature is not correct,
|
||||||
// this function returns ErrVarificationFailed.
|
// this function returns ErrVarificationFailed.
|
||||||
func Verify(publicKey []byte, docStr string) error {
|
func Verify(publicKey []byte, doc []byte) error {
|
||||||
ctx, err := newContext(publicKey)
|
ctx, err := newContext(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer closeContext(ctx)
|
defer closeContext(ctx)
|
||||||
|
|
||||||
doc, err := newDoc(docStr)
|
parsedDoc, err := newDoc(doc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer closeDoc(doc)
|
defer closeDoc(parsedDoc)
|
||||||
|
|
||||||
node := C.xmlSecFindNode(C.xmlDocGetRootElement(doc),
|
node := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
|
||||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
|
||||||
if node == nil {
|
if node == nil {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Un0PLcemAzPi8ADJlbMDG/IDXNbSej0Y4tw9Cdho1Q38XLZJi0RNdNvQJD1fWu3x
|
|||||||
9+QU/vJr7lMLzdoy
|
9+QU/vJr7lMLzdoy
|
||||||
-----END PRIVATE KEY-----`)
|
-----END PRIVATE KEY-----`)
|
||||||
|
|
||||||
docStr := `<?xml version="1.0" encoding="UTF-8"?>
|
docStr := []byte(`<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!--
|
||||||
XML Security Library example: Simple signature template file for sign1 example.
|
XML Security Library example: Simple signature template file for sign1 example.
|
||||||
-->
|
-->
|
||||||
@@ -58,18 +58,20 @@ XML Security Library example: Simple signature template file for sign1 example.
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if actualSignedString != expectedSignedString {
|
if string(actualSignedString) != expectedSignedString {
|
||||||
t.Errorf("signed: expected %q, got `%q`", expectedSignedString, actualSignedString)
|
t.Errorf("signed: expected %q, got `%q`", expectedSignedString, string(actualSignedString))
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := Verify(key, expectedSignedString); err != nil {
|
if err := Verify(key, []byte(expectedSignedString)); err != nil {
|
||||||
t.Errorf("verify: %s", err)
|
t.Errorf("verify: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
brokenDoc := strings.Replace(expectedSignedString, "Hello", "Goodbye", 1)
|
brokenDoc := strings.Replace(expectedSignedString, "Hello", "Goodbye", 1)
|
||||||
err = Verify(key, brokenDoc)
|
err = Verify(key, []byte(brokenDoc))
|
||||||
if err != ErrVerificationFailed {
|
if err != ErrVerificationFailed {
|
||||||
t.Errorf("verify: expected verification failed, got %s", err)
|
t.Errorf("verify: expected verification failed, got %s", err)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user