From 673471166ff7b06a650f2c623120f99280d72a0e Mon Sep 17 00:00:00 2001 From: Ross Kinder Date: Tue, 6 Oct 2015 12:41:06 -0400 Subject: [PATCH] fix Sign/Verify to take byte slices not strings --- examples/xmldsig.go | 6 +++--- xmldsig/xmldsig.go | 38 +++++++++++++++++++++----------------- xmldsig/xmldsig_test.go | 12 +++++++----- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/examples/xmldsig.go b/examples/xmldsig.go index 712c5b6..e07981a 100644 --- a/examples/xmldsig.go +++ b/examples/xmldsig.go @@ -33,16 +33,16 @@ func main() { buf, err := ioutil.ReadAll(os.Stdin) if *doSign { - signedBuf, err := xmldsig.Sign(key, string(buf)) + signedBuf, err := xmldsig.Sign(key, buf) if err != nil { fmt.Printf("%s\n", err) os.Exit(1) } - fmt.Print(signedBuf) + os.Stdout.Write(signedBuf) } if *doVerify { - err := xmldsig.Verify(key, string(buf)) + err := xmldsig.Verify(key, buf) if err == xmldsig.ErrVerificationFailed { fmt.Println("signature is not correct") os.Exit(1) diff --git a/xmldsig/xmldsig.go b/xmldsig/xmldsig.go index f445bdd..b701920 100644 --- a/xmldsig/xmldsig.go +++ b/xmldsig/xmldsig.go @@ -59,8 +59,9 @@ func closeContext(ctx *C.xmlSecDSigCtx) { C.xmlSecDSigCtxDestroy(ctx) } -func newDoc(s string) (*C.xmlDoc, error) { - ctx := C.xmlCreateMemoryParserCtxt(C.CString(s), C.int(len(s))) +func newDoc(buf []byte) (*C.xmlDoc, error) { + ctx := C.xmlCreateMemoryParserCtxt((*C.char)(unsafe.Pointer(&buf[0])), + C.int(len(buf))) if ctx == nil { return nil, errors.New("error creating parser") } @@ -80,13 +81,16 @@ func newDoc(s string) (*C.xmlDoc, error) { return doc, nil } -func dumpDoc(doc *C.xmlDoc) string { +func dumpDoc(doc *C.xmlDoc) []byte { var buffer *C.xmlChar var bufferSize C.int C.xmlDocDumpMemory(doc, &buffer, &bufferSize) rv := C.GoStringN((*C.char)(unsafe.Pointer(buffer)), bufferSize) 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) { @@ -97,31 +101,31 @@ func closeDoc(doc *C.xmlDoc) { // the XML-DSIG standard. docStr is a template document meaning // that it contains a `Signature` element in the // 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) if err != nil { - return "", err + return nil, err } defer closeContext(ctx) - doc, err := newDoc(docStr) + parsedDoc, err := newDoc(doc) 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.xmlSecDSigNs))) 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 { - 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 @@ -137,20 +141,20 @@ const ( // to the XML-DSIG specification. publicKey is the public part of // the key used to sign docStr. If the signature is not correct, // this function returns ErrVarificationFailed. -func Verify(publicKey []byte, docStr string) error { +func Verify(publicKey []byte, doc []byte) error { ctx, err := newContext(publicKey) if err != nil { return err } defer closeContext(ctx) - doc, err := newDoc(docStr) + parsedDoc, err := newDoc(doc) if err != nil { 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.xmlSecDSigNs))) if node == nil { diff --git a/xmldsig/xmldsig_test.go b/xmldsig/xmldsig_test.go index 2e8a95c..bcb4862 100644 --- a/xmldsig/xmldsig_test.go +++ b/xmldsig/xmldsig_test.go @@ -23,7 +23,7 @@ Un0PLcemAzPi8ADJlbMDG/IDXNbSej0Y4tw9Cdho1Q38XLZJi0RNdNvQJD1fWu3x 9+QU/vJr7lMLzdoy -----END PRIVATE KEY-----`) - docStr := ` + docStr := []byte(` @@ -58,18 +58,20 @@ XML Security Library example: Simple signature template file for sign1 example. return } - if actualSignedString != expectedSignedString { - t.Errorf("signed: expected %q, got `%q`", expectedSignedString, actualSignedString) + if string(actualSignedString) != expectedSignedString { + t.Errorf("signed: expected %q, got `%q`", expectedSignedString, string(actualSignedString)) + return + } return } - if err := Verify(key, expectedSignedString); err != nil { + if err := Verify(key, []byte(expectedSignedString)); err != nil { t.Errorf("verify: %s", err) return } brokenDoc := strings.Replace(expectedSignedString, "Hello", "Goodbye", 1) - err = Verify(key, brokenDoc) + err = Verify(key, []byte(brokenDoc)) if err != ErrVerificationFailed { t.Errorf("verify: expected verification failed, got %s", err) return