-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
crypto: ECDH convertKey to convert public keys between different formats #19080
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
Changes from 1 commit
41a17db
9ded80c
e876f36
810cb37
17f1703
d5f07d9
c201c26
541a651
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
ECDH.convertKey is used to convert public keys between different formats. Fixes: #18977
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5550,6 +5550,72 @@ void ExportChallenge(const FunctionCallbackInfo<Value>& args) { | |
| args.GetReturnValue().Set(outString); | ||
| } | ||
|
|
||
|
|
||
| // convert public key to compressed, uncompressed, hybrid format | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you capitalize and punctuate the comments? |
||
| void ConvertKey(const FunctionCallbackInfo<Value>& args) { | ||
| Environment* env = Environment::GetCurrent(args); | ||
|
|
||
| CHECK_EQ(args.Length(), 3); | ||
|
|
||
| THROW_AND_RETURN_IF_NOT_BUFFER(args[0], "Public key"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is adding a new API, please handle the input type checking in javascript and use the internal/errors mechanism.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! :) |
||
|
|
||
| size_t len = Buffer::Length(args[0]); | ||
| if (len == 0) | ||
| return args.GetReturnValue().SetEmptyString(); | ||
|
|
||
| THROW_AND_RETURN_IF_NOT_STRING(args[1], "ECDH curve name"); | ||
| node::Utf8Value curve(env->isolate(), args[1]); | ||
|
|
||
| int nid = OBJ_sn2nid(*curve); | ||
| if (nid == NID_undef) | ||
| return env->ThrowTypeError("Second argument should be a valid curve name"); | ||
|
|
||
| EC_GROUP* group = EC_GROUP_new_by_curve_name(nid); | ||
| 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"); | ||
|
|
||
| if (pub == nullptr) | ||
| return env->ThrowError("Failed to convert Buffer to EC_POINT"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| // convert to the specified format | ||
| int size; | ||
| point_conversion_form_t form = | ||
| static_cast<point_conversion_form_t>(args[2]->Uint32Value()); | ||
|
|
||
| size = EC_POINT_point2oct(group, pub, form, nullptr, 0, nullptr); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor thing but can you write this as |
||
| if (size == 0) | ||
| return env->ThrowError("Failed to get public key length"); | ||
|
|
||
| unsigned char* out = node::Malloc<unsigned char>(size); | ||
|
|
||
| r = EC_POINT_point2oct(group, pub, form, out, size, nullptr); | ||
| if (r != size) { | ||
| free(out); | ||
| return env->ThrowError("Failed to get public key"); | ||
| } | ||
|
|
||
| Local<Object> buf = | ||
| Buffer::New(env, reinterpret_cast<char*>(out), size).ToLocalChecked(); | ||
| args.GetReturnValue().Set(buf); | ||
|
|
||
| EC_GROUP_free(group); | ||
| EC_POINT_free(pub); | ||
| } | ||
|
|
||
|
|
||
| void TimingSafeEqual(const FunctionCallbackInfo<Value>& args) { | ||
| CHECK(Buffer::HasInstance(args[0])); | ||
| CHECK(Buffer::HasInstance(args[1])); | ||
|
|
@@ -5692,6 +5758,8 @@ void InitCrypto(Local<Object> target, | |
| env->SetMethod(target, "certVerifySpkac", VerifySpkac); | ||
| env->SetMethod(target, "certExportPublicKey", ExportPublicKey); | ||
| env->SetMethod(target, "certExportChallenge", ExportChallenge); | ||
|
|
||
| env->SetMethod(target, "ECDHConvertKey", ConvertKey); | ||
| #ifndef OPENSSL_NO_ENGINE | ||
| env->SetMethod(target, "setEngine", SetEngine); | ||
| #endif // !OPENSSL_NO_ENGINE | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't duplicate this logic, factor it out so it can be shared with
ECDH#getPublicKey(). Likewise the C++ code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!