Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src,crypto: refactor crypto_dh.cc #42492

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
87 changes: 58 additions & 29 deletions src/crypto/crypto_dh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

namespace node {

using v8::ArrayBuffer;
using v8::BackingStore;
using v8::ConstructorBehavior;
using v8::DontDelete;
using v8::FunctionCallback;
Expand All @@ -30,14 +32,13 @@ using v8::ReadOnly;
using v8::SideEffectType;
using v8::Signature;
using v8::String;
using v8::Uint8Array;
using v8::Value;

namespace crypto {
namespace {
static void ZeroPadDiffieHellmanSecret(size_t remainder_size,
char* data,
size_t length) {
void ZeroPadDiffieHellmanSecret(size_t remainder_size,
char* data,
size_t length) {
// DH_size returns number of bytes in a prime number.
// DH_compute_key returns number of bytes in a remainder of exponent, which
// may have less bytes than a prime number. Therefore add 0-padding to the
Expand All @@ -50,10 +51,6 @@ static void ZeroPadDiffieHellmanSecret(size_t remainder_size,
memset(data, 0, padding);
}
}
static void ZeroPadDiffieHellmanSecret(size_t remainder_size,
AllocatedBuffer* ret) {
ZeroPadDiffieHellmanSecret(remainder_size, ret->data(), ret->size());
}
} // namespace

DiffieHellman::DiffieHellman(Environment* env, Local<Object> wrap)
Expand Down Expand Up @@ -275,13 +272,24 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {

const BIGNUM* pub_key;
DH_get0_key(diffieHellman->dh_.get(), &pub_key, nullptr);
const int size = BN_num_bytes(pub_key);
CHECK_GE(size, 0);
AllocatedBuffer data = AllocatedBuffer::AllocateManaged(env, size);
CHECK_EQ(size,
BN_bn2binpad(
pub_key, reinterpret_cast<unsigned char*>(data.data()), size));
args.GetReturnValue().Set(data.ToBuffer().FromMaybe(Local<Value>()));

std::unique_ptr<BackingStore> bs;
{
const int size = BN_num_bytes(pub_key);
CHECK_GE(size, 0);
NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
bs = ArrayBuffer::NewBackingStore(env->isolate(), size);
}

CHECK_EQ(static_cast<int>(bs->ByteLength()),
BN_bn2binpad(pub_key,
static_cast<unsigned char*>(bs->Data()),
bs->ByteLength()));

Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(bs));
Local<Value> buffer;
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&buffer)) return;
args.GetReturnValue().Set(buffer);
}


Expand All @@ -297,13 +305,23 @@ void DiffieHellman::GetField(const FunctionCallbackInfo<Value>& args,
if (num == nullptr)
return THROW_ERR_CRYPTO_INVALID_STATE(env, err_if_null);

const int size = BN_num_bytes(num);
CHECK_GE(size, 0);
AllocatedBuffer data = AllocatedBuffer::AllocateManaged(env, size);
CHECK_EQ(
size,
BN_bn2binpad(num, reinterpret_cast<unsigned char*>(data.data()), size));
args.GetReturnValue().Set(data.ToBuffer().FromMaybe(Local<Value>()));
std::unique_ptr<BackingStore> bs;
{
const int size = BN_num_bytes(num);
CHECK_GE(size, 0);
NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
bs = ArrayBuffer::NewBackingStore(env->isolate(), size);
}

CHECK_EQ(static_cast<int>(bs->ByteLength()),
BN_bn2binpad(num,
static_cast<unsigned char*>(bs->Data()),
bs->ByteLength()));

Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(bs));
Local<Value> buffer;
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&buffer)) return;
args.GetReturnValue().Set(buffer);
}

void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
Expand Down Expand Up @@ -352,10 +370,14 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
return THROW_ERR_OUT_OF_RANGE(env, "secret is too big");
BignumPointer key(BN_bin2bn(key_buf.data(), key_buf.size(), nullptr));

AllocatedBuffer ret =
AllocatedBuffer::AllocateManaged(env, DH_size(diffieHellman->dh_.get()));
std::unique_ptr<BackingStore> bs;
{
NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
bs = ArrayBuffer::NewBackingStore(env->isolate(),
DH_size(diffieHellman->dh_.get()));
}

int size = DH_compute_key(reinterpret_cast<unsigned char*>(ret.data()),
int size = DH_compute_key(static_cast<unsigned char*>(bs->Data()),
key.get(),
diffieHellman->dh_.get());

Expand Down Expand Up @@ -383,9 +405,14 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
}

CHECK_GE(size, 0);
ZeroPadDiffieHellmanSecret(static_cast<size_t>(size), &ret);
ZeroPadDiffieHellmanSecret(size,
static_cast<char*>(bs->Data()),
bs->ByteLength());

args.GetReturnValue().Set(ret.ToBuffer().FromMaybe(Local<Value>()));
Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(bs));
Local<Value> buffer;
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&buffer)) return;
args.GetReturnValue().Set(buffer);
}

void DiffieHellman::SetKey(const FunctionCallbackInfo<Value>& args,
Expand Down Expand Up @@ -609,8 +636,10 @@ void DiffieHellman::Stateless(const FunctionCallbackInfo<Value>& args) {
ManagedEVPPKey our_key = our_key_object->Data()->GetAsymmetricKey();
ManagedEVPPKey their_key = their_key_object->Data()->GetAsymmetricKey();

Local<Value> out = StatelessDiffieHellmanThreadsafe(our_key, their_key)
.ToBuffer(env).FromMaybe(Local<Uint8Array>());
Local<Value> out;
if (!StatelessDiffieHellmanThreadsafe(our_key, their_key)
.ToBuffer(env)
.ToLocal(&out)) return;

if (Buffer::Length(out) == 0)
return ThrowCryptoError(env, ERR_get_error(), "diffieHellman failed");
Expand Down