diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2017-07-10 12:56:37 +0200 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2017-07-17 23:09:34 +0200 |
commit | d70f2470d3024c137848e4c90ff2ded26492850e (patch) | |
tree | f7a74d751aad2b84219b790e48d0eb1a1737a118 /src | |
parent | a3b9f4b452a7dbc122713b7a5a2f550f686f1d8e (diff) | |
download | android-node-v8-d70f2470d3024c137848e4c90ff2ded26492850e.tar.gz android-node-v8-d70f2470d3024c137848e4c90ff2ded26492850e.tar.bz2 android-node-v8-d70f2470d3024c137848e4c90ff2ded26492850e.zip |
src: remove extra heap allocations in DH functions
Replace allocate + Encode() + free patterns by calls to Malloc +
the Buffer::New() overload that takes ownership of the pointer.
Avoids unnecessary heap allocations and copying around of data.
DRY the accessor functions for the prime, generator, public key and
private key properties; deletes about 40 lines of quadruplicated code.
PR-URL: https://github.com/nodejs/node/pull/14122
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/node_crypto.cc | 106 | ||||
-rw-r--r-- | src/node_crypto.h | 2 |
2 files changed, 31 insertions, 77 deletions
diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 573688e251..778efd2fcf 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4762,99 +4762,49 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) { return ThrowCryptoError(env, ERR_get_error(), "Key generation failed"); } - int dataSize = BN_num_bytes(diffieHellman->dh->pub_key); - char* data = new char[dataSize]; - BN_bn2bin(diffieHellman->dh->pub_key, - reinterpret_cast<unsigned char*>(data)); - - args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER)); - delete[] data; + size_t size = BN_num_bytes(diffieHellman->dh->pub_key); + char* data = Malloc(size); + BN_bn2bin(diffieHellman->dh->pub_key, reinterpret_cast<unsigned char*>(data)); + args.GetReturnValue().Set(Buffer::New(env, data, size).ToLocalChecked()); } -void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) { +void DiffieHellman::GetField(const FunctionCallbackInfo<Value>& args, + BIGNUM* (DH::*field), const char* err_if_null) { Environment* env = Environment::GetCurrent(args); - DiffieHellman* diffieHellman; - ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder()); + DiffieHellman* dh; + ASSIGN_OR_RETURN_UNWRAP(&dh, args.Holder()); + if (!dh->initialised_) return env->ThrowError("Not initialized"); - if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); - } + const BIGNUM* num = (dh->dh)->*field; + if (num == nullptr) return env->ThrowError(err_if_null); - int dataSize = BN_num_bytes(diffieHellman->dh->p); - char* data = new char[dataSize]; - BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data)); + size_t size = BN_num_bytes(num); + char* data = Malloc(size); + BN_bn2bin(num, reinterpret_cast<unsigned char*>(data)); + args.GetReturnValue().Set(Buffer::New(env, data, size).ToLocalChecked()); +} - args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER)); - delete[] data; +void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) { + GetField(args, &DH::p, "p is null"); } void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) { - Environment* env = Environment::GetCurrent(args); - - DiffieHellman* diffieHellman; - ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder()); - - if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); - } - - int dataSize = BN_num_bytes(diffieHellman->dh->g); - char* data = new char[dataSize]; - BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data)); - - args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER)); - delete[] data; + GetField(args, &DH::g, "g is null"); } void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) { - Environment* env = Environment::GetCurrent(args); - - DiffieHellman* diffieHellman; - ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder()); - - if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); - } - - if (diffieHellman->dh->pub_key == nullptr) { - return env->ThrowError("No public key - did you forget to generate one?"); - } - - int dataSize = BN_num_bytes(diffieHellman->dh->pub_key); - char* data = new char[dataSize]; - BN_bn2bin(diffieHellman->dh->pub_key, - reinterpret_cast<unsigned char*>(data)); - - args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER)); - delete[] data; + GetField(args, &DH::pub_key, + "No public key - did you forget to generate one?"); } void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) { - Environment* env = Environment::GetCurrent(args); - - DiffieHellman* diffieHellman; - ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder()); - - if (!diffieHellman->initialised_) { - return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); - } - - if (diffieHellman->dh->priv_key == nullptr) { - return env->ThrowError("No private key - did you forget to generate one?"); - } - - int dataSize = BN_num_bytes(diffieHellman->dh->priv_key); - char* data = new char[dataSize]; - BN_bn2bin(diffieHellman->dh->priv_key, - reinterpret_cast<unsigned char*>(data)); - - args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER)); - delete[] data; + GetField(args, &DH::priv_key, + "No private key - did you forget to generate one?"); } @@ -4882,7 +4832,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) { } int dataSize = DH_size(diffieHellman->dh); - char* data = new char[dataSize]; + char* data = Malloc(dataSize); int size = DH_compute_key(reinterpret_cast<unsigned char*>(data), key, @@ -4894,7 +4844,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) { checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult); BN_free(key); - delete[] data; + free(data); if (!checked) { return ThrowCryptoError(env, ERR_get_error(), "Invalid Key"); @@ -4909,6 +4859,8 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) { } else { return env->ThrowError("Invalid key"); } + + UNREACHABLE(); } BN_free(key); @@ -4924,8 +4876,8 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) { memset(data, 0, dataSize - size); } - args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER)); - delete[] data; + auto rc = Buffer::New(env->isolate(), data, dataSize).ToLocalChecked(); + args.GetReturnValue().Set(rc); } diff --git a/src/node_crypto.h b/src/node_crypto.h index eb5ca2b770..01c799a8b1 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -690,6 +690,8 @@ class DiffieHellman : public BaseObject { } private: + static void GetField(const v8::FunctionCallbackInfo<v8::Value>& args, + BIGNUM* (DH::*field), const char* err_if_null); bool VerifyContext(); bool initialised_; |