Skip to content

Commit c7b95fc

Browse files
jasnelladuh95
authored andcommitted
src: update ECPointPointer in ncrypto
PR-URL: #56526 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent c008b15 commit c7b95fc

File tree

3 files changed

+97
-41
lines changed

3 files changed

+97
-41
lines changed

deps/ncrypto/ncrypto.cc

+42
Original file line numberDiff line numberDiff line change
@@ -2707,4 +2707,46 @@ ECGroupPointer ECGroupPointer::NewByCurveName(int nid) {
27072707
return ECGroupPointer(EC_GROUP_new_by_curve_name(nid));
27082708
}
27092709

2710+
// ============================================================================
2711+
2712+
ECPointPointer::ECPointPointer() : point_(nullptr) {}
2713+
2714+
ECPointPointer::ECPointPointer(EC_POINT* point) : point_(point) {}
2715+
2716+
ECPointPointer::ECPointPointer(ECPointPointer&& other) noexcept
2717+
: point_(other.release()) {}
2718+
2719+
ECPointPointer& ECPointPointer::operator=(ECPointPointer&& other) noexcept {
2720+
point_.reset(other.release());
2721+
return *this;
2722+
}
2723+
2724+
ECPointPointer::~ECPointPointer() {
2725+
reset();
2726+
}
2727+
2728+
void ECPointPointer::reset(EC_POINT* point) {
2729+
point_.reset(point);
2730+
}
2731+
2732+
EC_POINT* ECPointPointer::release() {
2733+
return point_.release();
2734+
}
2735+
2736+
ECPointPointer ECPointPointer::New(const EC_GROUP* group) {
2737+
return ECPointPointer(EC_POINT_new(group));
2738+
}
2739+
2740+
bool ECPointPointer::setFromBuffer(const Buffer<const unsigned char>& buffer,
2741+
const EC_GROUP* group) {
2742+
if (!point_) return false;
2743+
return EC_POINT_oct2point(
2744+
group, point_.get(), buffer.data, buffer.len, nullptr);
2745+
}
2746+
2747+
bool ECPointPointer::mul(const EC_GROUP* group, const BIGNUM* priv_key) {
2748+
if (!point_) return false;
2749+
return EC_POINT_mul(group, point_.get(), priv_key, nullptr, nullptr, nullptr);
2750+
}
2751+
27102752
} // namespace ncrypto

deps/ncrypto/ncrypto.h

+26-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ using DeleteFnPtr = typename FunctionDeleter<T, function>::Pointer;
198198
using BignumCtxPointer = DeleteFnPtr<BN_CTX, BN_CTX_free>;
199199
using BignumGenCallbackPointer = DeleteFnPtr<BN_GENCB, BN_GENCB_free>;
200200
using ECKeyPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>;
201-
using ECPointPointer = DeleteFnPtr<EC_POINT, EC_POINT_free>;
202201
using EVPKeyCtxPointer = DeleteFnPtr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
203202
using EVPMDCtxPointer = DeleteFnPtr<EVP_MD_CTX, EVP_MD_CTX_free>;
204203
using HMACCtxPointer = DeleteFnPtr<HMAC_CTX, HMAC_CTX_free>;
@@ -873,6 +872,32 @@ class ECGroupPointer final {
873872
DeleteFnPtr<EC_GROUP, EC_GROUP_free> group_;
874873
};
875874

875+
class ECPointPointer final {
876+
public:
877+
ECPointPointer();
878+
explicit ECPointPointer(EC_POINT* point);
879+
ECPointPointer(ECPointPointer&& other) noexcept;
880+
ECPointPointer& operator=(ECPointPointer&& other) noexcept;
881+
NCRYPTO_DISALLOW_COPY(ECPointPointer)
882+
~ECPointPointer();
883+
884+
inline bool operator==(std::nullptr_t) noexcept { return point_ == nullptr; }
885+
inline operator bool() const { return point_ != nullptr; }
886+
inline EC_POINT* get() const { return point_.get(); }
887+
inline operator EC_POINT*() const { return point_.get(); }
888+
void reset(EC_POINT* point = nullptr);
889+
EC_POINT* release();
890+
891+
bool setFromBuffer(const Buffer<const unsigned char>& buffer,
892+
const EC_GROUP* group);
893+
bool mul(const EC_GROUP* group, const BIGNUM* priv_key);
894+
895+
static ECPointPointer New(const EC_GROUP* group);
896+
897+
private:
898+
DeleteFnPtr<EC_POINT, EC_POINT_free> point_;
899+
};
900+
876901
#ifndef OPENSSL_NO_ENGINE
877902
class EnginePointer final {
878903
public:

src/crypto/crypto_ec.cc

+29-40
Original file line numberDiff line numberDiff line change
@@ -157,28 +157,26 @@ void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
157157
ECPointPointer ECDH::BufferToPoint(Environment* env,
158158
const EC_GROUP* group,
159159
Local<Value> buf) {
160-
int r;
160+
ArrayBufferOrViewContents<unsigned char> input(buf);
161+
if (!input.CheckSizeInt32()) [[unlikely]] {
162+
THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
163+
return {};
164+
}
161165

162-
ECPointPointer pub(EC_POINT_new(group));
166+
auto pub = ECPointPointer::New(group);
163167
if (!pub) {
164168
THROW_ERR_CRYPTO_OPERATION_FAILED(env,
165169
"Failed to allocate EC_POINT for a public key");
166170
return pub;
167171
}
168172

169-
ArrayBufferOrViewContents<unsigned char> input(buf);
170-
if (!input.CheckSizeInt32()) [[unlikely]] {
171-
THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
172-
return ECPointPointer();
173+
ncrypto::Buffer<const unsigned char> buffer{
174+
.data = input.data(),
175+
.len = input.size(),
176+
};
177+
if (!pub.setFromBuffer(buffer, group)) {
178+
return {};
173179
}
174-
r = EC_POINT_oct2point(
175-
group,
176-
pub.get(),
177-
input.data(),
178-
input.size(),
179-
nullptr);
180-
if (!r)
181-
return ECPointPointer();
182180

183181
return pub;
184182
}
@@ -196,10 +194,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
196194
if (!ecdh->IsKeyPairValid())
197195
return THROW_ERR_CRYPTO_INVALID_KEYPAIR(env);
198196

199-
ECPointPointer pub(
200-
ECDH::BufferToPoint(env,
201-
ecdh->group_,
202-
args[0]));
197+
auto pub = ECDH::BufferToPoint(env, ecdh->group_, args[0]);
203198
if (!pub) {
204199
args.GetReturnValue().Set(
205200
FIXED_ONE_BYTE_STRING(env->isolate(),
@@ -217,7 +212,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
217212
}
218213

219214
if (!ECDH_compute_key(
220-
bs->Data(), bs->ByteLength(), pub.get(), ecdh->key_.get(), nullptr))
215+
bs->Data(), bs->ByteLength(), pub, ecdh->key_.get(), nullptr))
221216
return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to compute ECDH key");
222217

223218
Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(bs));
@@ -317,16 +312,15 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
317312
const BIGNUM* priv_key = EC_KEY_get0_private_key(new_key.get());
318313
CHECK_NOT_NULL(priv_key);
319314

320-
ECPointPointer pub(EC_POINT_new(ecdh->group_));
315+
auto pub = ECPointPointer::New(ecdh->group_);
321316
CHECK(pub);
322317

323-
if (!EC_POINT_mul(ecdh->group_, pub.get(), priv_key,
324-
nullptr, nullptr, nullptr)) {
318+
if (!pub.mul(ecdh->group_, priv_key)) {
325319
return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
326320
"Failed to generate ECDH public key");
327321
}
328322

329-
if (!EC_KEY_set_public_key(new_key.get(), pub.get()))
323+
if (!EC_KEY_set_public_key(new_key.get(), pub))
330324
return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
331325
"Failed to set generated public key");
332326

@@ -344,16 +338,13 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
344338

345339
MarkPopErrorOnReturn mark_pop_error_on_return;
346340

347-
ECPointPointer pub(
348-
ECDH::BufferToPoint(env,
349-
ecdh->group_,
350-
args[0]));
341+
auto pub = ECDH::BufferToPoint(env, ecdh->group_, args[0]);
351342
if (!pub) {
352343
return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
353344
"Failed to convert Buffer to EC_POINT");
354345
}
355346

356-
int r = EC_KEY_set_public_key(ecdh->key_.get(), pub.get());
347+
int r = EC_KEY_set_public_key(ecdh->key_.get(), pub);
357348
if (!r) {
358349
return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
359350
"Failed to set EC_POINT as the public key");
@@ -403,9 +394,8 @@ void ECDH::ConvertKey(const FunctionCallbackInfo<Value>& args) {
403394
if (!group)
404395
return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to get EC_GROUP");
405396

406-
ECPointPointer pub(ECDH::BufferToPoint(env, group, args[0]));
407-
408-
if (pub == nullptr) {
397+
auto pub = ECDH::BufferToPoint(env, group, args[0]);
398+
if (!pub) {
409399
return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
410400
"Failed to convert Buffer to EC_POINT");
411401
}
@@ -416,7 +406,7 @@ void ECDH::ConvertKey(const FunctionCallbackInfo<Value>& args) {
416406

417407
const char* error;
418408
Local<Object> buf;
419-
if (!ECPointToBuffer(env, group, pub.get(), form, &error).ToLocal(&buf))
409+
if (!ECPointToBuffer(env, group, pub, form, &error).ToLocal(&buf))
420410
return THROW_ERR_CRYPTO_OPERATION_FAILED(env, error);
421411
args.GetReturnValue().Set(buf);
422412
}
@@ -698,14 +688,13 @@ WebCryptoKeyExportStatus ECKeyExportTraits::DoExport(
698688
if (have == 0) return WebCryptoKeyExportStatus::FAILED;
699689
ECKeyPointer ec(EC_KEY_new());
700690
CHECK_EQ(1, EC_KEY_set_group(ec.get(), group));
701-
ECPointPointer uncompressed(EC_POINT_new(group));
702-
CHECK_EQ(1,
703-
EC_POINT_oct2point(group,
704-
uncompressed.get(),
705-
data.data<unsigned char>(),
706-
data.size(),
707-
nullptr));
708-
CHECK_EQ(1, EC_KEY_set_public_key(ec.get(), uncompressed.get()));
691+
auto uncompressed = ECPointPointer::New(group);
692+
ncrypto::Buffer<const unsigned char> buffer{
693+
.data = data.data<unsigned char>(),
694+
.len = data.size(),
695+
};
696+
CHECK(uncompressed.setFromBuffer(buffer, group));
697+
CHECK_EQ(1, EC_KEY_set_public_key(ec.get(), uncompressed));
709698
auto pkey = EVPKeyPointer::New();
710699
CHECK_EQ(1, EVP_PKEY_set1_EC_KEY(pkey.get(), ec.get()));
711700
auto bio = pkey.derPublicKey();

0 commit comments

Comments
 (0)