diff --git a/ed25519.go b/ed25519.go index 4a1d175d..f74bd8f8 100644 --- a/ed25519.go +++ b/ed25519.go @@ -145,12 +145,12 @@ func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) { } func extractPKEYPubEd25519(pkey C.GO_EVP_PKEY_PTR, pub []byte) error { - pubSize := C.size_t(publicKeySizeEd25519) - if C.go_openssl_EVP_PKEY_get_raw_public_key_wrapper(pkey, base(pub), pubSize) != 1 { + r := C.go_openssl_EVP_PKEY_get_raw_public_key_wrapper(pkey, base(pub), C.size_t(publicKeySizeEd25519)) + if r.result != 1 { return newOpenSSLError("EVP_PKEY_get_raw_public_key") } - if pubSize != publicKeySizeEd25519 { - return errors.New("ed25519: bad public key length: " + strconv.Itoa(int(pubSize))) + if r.len != publicKeySizeEd25519 { + return errors.New("ed25519: bad public key length: " + strconv.Itoa(int(r.len))) } return nil } @@ -159,12 +159,12 @@ func extractPKEYPrivEd25519(pkey C.GO_EVP_PKEY_PTR, priv []byte) error { if err := extractPKEYPubEd25519(pkey, priv[seedSizeEd25519:]); err != nil { return err } - privSize := C.size_t(seedSizeEd25519) - if C.go_openssl_EVP_PKEY_get_raw_private_key_wrapper(pkey, base(priv), privSize) != 1 { + r := C.go_openssl_EVP_PKEY_get_raw_private_key_wrapper(pkey, base(priv), C.size_t(seedSizeEd25519)) + if r.result != 1 { return newOpenSSLError("EVP_PKEY_get_raw_private_key") } - if privSize != seedSizeEd25519 { - return errors.New("ed25519: bad private key length: " + strconv.Itoa(int(privSize))) + if r.len != seedSizeEd25519 { + return errors.New("ed25519: bad private key length: " + strconv.Itoa(int(r.len))) } return nil } diff --git a/goopenssl.h b/goopenssl.h index 3401a13e..c3dc6366 100644 --- a/goopenssl.h +++ b/goopenssl.h @@ -82,9 +82,8 @@ go_hash_sum(GO_EVP_MD_CTX_PTR ctx, GO_EVP_MD_CTX_PTR ctx2, unsigned char *out) return go_openssl_EVP_DigestFinal(ctx2, out, NULL); } -// These wrappers allocate length variables on the C stack to avoid having to pass a pointer from Go, which would escape to the heap. +// These wrappers allocate out_len on the C stack to avoid having to pass a pointer from Go, which would escape to the heap. // Use them only in situations where the output length can be safely discarded. - static inline int go_openssl_EVP_EncryptUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) { @@ -106,18 +105,6 @@ go_openssl_EVP_CipherUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *ou return go_openssl_EVP_CipherUpdate(ctx, out, &len, in, in_len); } -static inline int -go_openssl_EVP_PKEY_get_raw_public_key_wrapper(const GO_EVP_PKEY_PTR pkey, unsigned char *pub, size_t len) -{ - return go_openssl_EVP_PKEY_get_raw_public_key(pkey, pub, &len); -} - -static inline int -go_openssl_EVP_PKEY_get_raw_private_key_wrapper(const GO_EVP_PKEY_PTR pkey, unsigned char *priv, size_t len) -{ - return go_openssl_EVP_PKEY_get_raw_private_key(pkey, priv, &len); -} - // These wrappers also allocate length variables on the C stack to avoid escape to the heap, but do return the result. // A struct is returned that contains multiple return values instead of OpenSSL's approach of using pointers. @@ -135,6 +122,28 @@ go_openssl_EVP_PKEY_derive_wrapper(GO_EVP_PKEY_CTX_PTR ctx, unsigned char *key, return r; } +typedef struct +{ + int result; + size_t len; +} go_openssl_EVP_PKEY_get_raw_key_out; + +static inline go_openssl_EVP_PKEY_get_raw_key_out +go_openssl_EVP_PKEY_get_raw_public_key_wrapper(const GO_EVP_PKEY_PTR pkey, unsigned char *pub, size_t len) +{ + go_openssl_EVP_PKEY_get_raw_key_out r = {0, len}; + r.result = go_openssl_EVP_PKEY_get_raw_public_key(pkey, pub, &r.len); + return r; +} + +static inline go_openssl_EVP_PKEY_get_raw_key_out +go_openssl_EVP_PKEY_get_raw_private_key_wrapper(const GO_EVP_PKEY_PTR pkey, unsigned char *priv, size_t len) +{ + go_openssl_EVP_PKEY_get_raw_key_out r = {0, len}; + r.result = go_openssl_EVP_PKEY_get_raw_private_key(pkey, priv, &r.len); + return r; +} + typedef struct { int result;