fix Sign/Verify to take byte slices not strings

This commit is contained in:
Ross Kinder
2015-10-06 12:41:06 -04:00
parent 109617ef26
commit 673471166f
3 changed files with 31 additions and 25 deletions

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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