Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
crypto: refactoring shared code
refactored ECDH::BufferToPoint and
key formatting
  • Loading branch information
wuweiweiwu committed Mar 10, 2018
commit 9ded80cc0dd854788979b7c1118283598adaaf0c
38 changes: 16 additions & 22 deletions lib/internal/crypto/diffiehellman.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,31 +198,28 @@ ECDH.prototype.generateKeys = function generateKeys(encoding, format) {
};

ECDH.prototype.getPublicKey = function getPublicKey(encoding, format) {
var f;
if (format) {
if (format === 'compressed')
f = POINT_CONVERSION_COMPRESSED;
else if (format === 'hybrid')
f = POINT_CONVERSION_HYBRID;
// Default
else if (format === 'uncompressed')
f = POINT_CONVERSION_UNCOMPRESSED;
else
throw new ERR_CRYPTO_ECDH_INVALID_FORMAT(format);
} else {
f = POINT_CONVERSION_UNCOMPRESSED;
}
var f = getFormat(format);
var key = this._handle.getPublicKey(f);
encoding = encoding || getDefaultEncoding();
if (encoding && encoding !== 'buffer')
key = key.toString(encoding);
return key;
return encode(key, encoding);
};

ECDH.convertKey = function convertKey(key, curve, inEnc, outEnc, format) {
const encoding = getDefaultEncoding();
inEnc = inEnc || encoding;
outEnc = outEnc || encoding;
var f = getFormat(format);
var convertedKey = _ECDHConvertKey(toBuf(key, inEnc), curve, f);
return encode(convertedKey, outEnc);
};

function encode(buffer, encoding) {
Copy link
Copy Markdown
Contributor Author

@wuweiweiwu wuweiweiwu Mar 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bnoordhuis I also added the encode function since I noticed that the test for 'buffer' encoding happens a lot in this file. Should I also change that in this PR or should I submit another PR for that?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, doing it in this PR is fine.

if (encoding && encoding !== 'buffer')
buffer = buffer.toString(encoding);
return buffer;
}

function getFormat(format) {
var f;
if (format) {
if (format === 'compressed')
Expand All @@ -237,11 +234,8 @@ ECDH.convertKey = function convertKey(key, curve, inEnc, outEnc, format) {
} else {
f = POINT_CONVERSION_UNCOMPRESSED;
}
var convertedKey = _ECDHConvertKey(toBuf(key, inEnc), curve, f);
if (outEnc && outEnc !== 'buffer')
convertedKey = convertedKey.toString(outEnc);
return convertedKey;
};
return f;
}

module.exports = {
DiffieHellman,
Expand Down
38 changes: 18 additions & 20 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4684,18 +4684,21 @@ void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
}


EC_POINT* ECDH::BufferToPoint(char* data, size_t len) {
EC_POINT* ECDH::BufferToPoint(Environment* env,
const EC_GROUP* group,
char* data,
size_t len) {
EC_POINT* pub;
int r;

pub = EC_POINT_new(group_);
pub = EC_POINT_new(group);
if (pub == nullptr) {
env()->ThrowError("Failed to allocate EC_POINT for a public key");
env->ThrowError("Failed to allocate EC_POINT for a public key");
return nullptr;
}

r = EC_POINT_oct2point(
group_,
group,
pub,
reinterpret_cast<unsigned char*>(data),
len,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're making changes here, you might want to get rid of the goto by moving the fatal: block inside the if statement.

Copy link
Copy Markdown
Contributor Author

@wuweiweiwu wuweiweiwu Mar 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Expand Down Expand Up @@ -4725,7 +4728,9 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
if (!ecdh->IsKeyPairValid())
return env->ThrowError("Invalid key pair");

EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0]),
EC_POINT* pub = ECDH::BufferToPoint(env,
ecdh->group_,
Buffer::Data(args[0]),
Buffer::Length(args[0]));
if (pub == nullptr) {
args.GetReturnValue().Set(
Expand Down Expand Up @@ -4874,7 +4879,9 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {

MarkPopErrorOnReturn mark_pop_error_on_return;

EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0].As<Object>()),
EC_POINT* pub = ECDH::BufferToPoint(env,
ecdh->group_,
Buffer::Data(args[0].As<Object>()),
Buffer::Length(args[0].As<Object>()));
if (pub == nullptr)
return env->ThrowError("Failed to convert Buffer to EC_POINT");
Expand Down Expand Up @@ -5574,19 +5581,10 @@ void ConvertKey(const FunctionCallbackInfo<Value>& args) {
if (group == nullptr)
return env->ThrowError("Failed to get EC_GROUP");

EC_POINT* pub = EC_POINT_new(group);
if (pub == nullptr)
return env->ThrowError("Failed to allocate EC_POINT for a public key");

int r = EC_POINT_oct2point(
group,
pub,
reinterpret_cast<unsigned char*>(Buffer::Data(args[0])),
len,
nullptr);
if (!r)
return env->ThrowError("Failed to convert key to point");

EC_POINT* pub = ECDH::BufferToPoint(env,
group,
Buffer::Data(args[0]),
len);
if (pub == nullptr)
return env->ThrowError("Failed to convert Buffer to EC_POINT");
Copy link
Copy Markdown
Member

@bnoordhuis bnoordhuis Mar 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaks group. group and pub are leaked on lines 5580 and 5587.

Suggestion: use a std::unique_ptr with a custom deleter or use the std::shared_ptr trick from 8ccd320.


Expand All @@ -5601,7 +5599,7 @@ void ConvertKey(const FunctionCallbackInfo<Value>& args) {

unsigned char* out = node::Malloc<unsigned char>(size);

r = EC_POINT_point2oct(group, pub, form, out, size, nullptr);
int r = EC_POINT_point2oct(group, pub, form, out, size, nullptr);
if (r != size) {
free(out);
return env->ThrowError("Failed to get public key");
Expand Down
6 changes: 4 additions & 2 deletions src/node_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,10 @@ class ECDH : public BaseObject {
}

static void Initialize(Environment* env, v8::Local<v8::Object> target);
static EC_POINT* BufferToPoint(Environment* env,
const EC_GROUP* group,
char* data,
size_t len);

protected:
ECDH(Environment* env, v8::Local<v8::Object> wrap, EC_KEY* key)
Expand All @@ -643,8 +647,6 @@ class ECDH : public BaseObject {
static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);

EC_POINT* BufferToPoint(char* data, size_t len);

bool IsKeyPairValid();
bool IsKeyValidForCurve(const BIGNUM* private_key);

Expand Down