From 46da5280eb7fe9fafabaee5c7202732fa15a034a Mon Sep 17 00:00:00 2001 From: "Joe Richey joerichey@google.com" Date: Mon, 17 Jul 2017 17:15:15 -0700 Subject: [PATCH] crypto: Conversion to/from C strings --- crypto/key.go | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/crypto/key.go b/crypto/key.go index cffe2b4..e440ca1 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -20,6 +20,12 @@ package crypto +/* +#include +#include +*/ +import "C" + import ( "bytes" "crypto/subtle" @@ -148,13 +154,6 @@ func (key *Key) Len() int { return len(key.data) } -// UnsafeData exposes the underlying protected slice. This is unsafe because the -// data can be paged to disk if the buffer is copied, or the slice may be -// wiped while being used. -func (key *Key) UnsafeData() []byte { - return key.data -} - // Equals compares the contents of two keys, returning true if they have the same // key data. This function runs in constant time. func (key *Key) Equals(key2 *Key) bool { @@ -178,6 +177,30 @@ func (key *Key) resize(requestedSize int) (*Key, error) { return resizedKey, nil } +// UnsafeToCString makes a copy of the string's data into a null-terminated C +// string allocated by C. Note that this method is unsafe as this C copy has no +// locking or wiping functionality. The key shouldn't contain any `\0` bytes. +func (key *Key) UnsafeToCString() unsafe.Pointer { + // Memory for the key must be moved into a C string allocated by C. + size := C.size_t(key.Len()) + data := C.calloc(size+1, 1) + C.memcpy(data, util.Ptr(key.data), size) + return data +} + +// NewKeyFromCString creates of a copy of some C string's data in a key. Note +// that the original C string is not modified at all, so steps must be taken to +// ensure that this original copy is secured. +func NewKeyFromCString(str unsafe.Pointer) (*Key, error) { + size := C.strlen((*C.char)(str)) + key, err := newBlankKey(int(size)) + if err != nil { + return nil, err + } + C.memcpy(util.Ptr(key.data), str, size) + return key, nil +} + // NewKeyFromReader constructs a key of abritary length by reading from reader // until hitting EOF. func NewKeyFromReader(reader io.Reader) (*Key, error) { -- 2.39.5