Skip to content

Commit 5673dc7

Browse files
jasnelladuh95
authored andcommitted
src: update ECDASSigPointer implementation in ncrypto
PR-URL: #56526 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 87ba48b commit 5673dc7

File tree

4 files changed

+110
-19
lines changed

4 files changed

+110
-19
lines changed

deps/ncrypto/ncrypto.cc

+64
Original file line numberDiff line numberDiff line change
@@ -2613,4 +2613,68 @@ bool CipherCtxPointer::getAeadTag(size_t len, unsigned char* out) {
26132613
return EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG, len, out);
26142614
}
26152615

2616+
// ============================================================================
2617+
2618+
ECDSASigPointer::ECDSASigPointer() : sig_(nullptr) {}
2619+
ECDSASigPointer::ECDSASigPointer(ECDSA_SIG* sig) : sig_(sig) {
2620+
if (sig_) {
2621+
ECDSA_SIG_get0(sig_.get(), &pr_, &ps_);
2622+
}
2623+
}
2624+
ECDSASigPointer::ECDSASigPointer(ECDSASigPointer&& other) noexcept
2625+
: sig_(other.release()) {
2626+
if (sig_) {
2627+
ECDSA_SIG_get0(sig_.get(), &pr_, &ps_);
2628+
}
2629+
}
2630+
2631+
ECDSASigPointer& ECDSASigPointer::operator=(ECDSASigPointer&& other) noexcept {
2632+
sig_.reset(other.release());
2633+
if (sig_) {
2634+
ECDSA_SIG_get0(sig_.get(), &pr_, &ps_);
2635+
}
2636+
return *this;
2637+
}
2638+
2639+
ECDSASigPointer::~ECDSASigPointer() {
2640+
reset();
2641+
}
2642+
2643+
void ECDSASigPointer::reset(ECDSA_SIG* sig) {
2644+
sig_.reset();
2645+
pr_ = nullptr;
2646+
ps_ = nullptr;
2647+
}
2648+
2649+
ECDSA_SIG* ECDSASigPointer::release() {
2650+
pr_ = nullptr;
2651+
ps_ = nullptr;
2652+
return sig_.release();
2653+
}
2654+
2655+
ECDSASigPointer ECDSASigPointer::New() {
2656+
return ECDSASigPointer(ECDSA_SIG_new());
2657+
}
2658+
2659+
ECDSASigPointer ECDSASigPointer::Parse(const Buffer<const unsigned char>& sig) {
2660+
const unsigned char* ptr = sig.data;
2661+
return ECDSASigPointer(d2i_ECDSA_SIG(nullptr, &ptr, sig.len));
2662+
}
2663+
2664+
bool ECDSASigPointer::setParams(BignumPointer&& r, BignumPointer&& s) {
2665+
if (!sig_) return false;
2666+
return ECDSA_SIG_set0(sig_.get(), r.release(), s.release());
2667+
}
2668+
2669+
Buffer<unsigned char> ECDSASigPointer::encode() const {
2670+
if (!sig_)
2671+
return {
2672+
.data = nullptr,
2673+
.len = 0,
2674+
};
2675+
Buffer<unsigned char> buf;
2676+
buf.len = i2d_ECDSA_SIG(sig_.get(), &buf.data);
2677+
return buf;
2678+
}
2679+
26162680
} // namespace ncrypto

deps/ncrypto/ncrypto.h

+32-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ using DeleteFnPtr = typename FunctionDeleter<T, function>::Pointer;
197197

198198
using BignumCtxPointer = DeleteFnPtr<BN_CTX, BN_CTX_free>;
199199
using BignumGenCallbackPointer = DeleteFnPtr<BN_GENCB, BN_GENCB_free>;
200-
using ECDSASigPointer = DeleteFnPtr<ECDSA_SIG, ECDSA_SIG_free>;
201200
using ECGroupPointer = DeleteFnPtr<EC_GROUP, EC_GROUP_free>;
202201
using ECKeyPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>;
203202
using ECPointPointer = DeleteFnPtr<EC_POINT, EC_POINT_free>;
@@ -821,6 +820,38 @@ class X509Pointer final {
821820
DeleteFnPtr<X509, X509_free> cert_;
822821
};
823822

823+
class ECDSASigPointer final {
824+
public:
825+
explicit ECDSASigPointer();
826+
explicit ECDSASigPointer(ECDSA_SIG* sig);
827+
ECDSASigPointer(ECDSASigPointer&& other) noexcept;
828+
ECDSASigPointer& operator=(ECDSASigPointer&& other) noexcept;
829+
NCRYPTO_DISALLOW_COPY(ECDSASigPointer)
830+
~ECDSASigPointer();
831+
832+
inline bool operator==(std::nullptr_t) noexcept { return sig_ == nullptr; }
833+
inline operator bool() const { return sig_ != nullptr; }
834+
inline ECDSA_SIG* get() const { return sig_.get(); }
835+
inline operator ECDSA_SIG*() const { return sig_.get(); }
836+
void reset(ECDSA_SIG* sig = nullptr);
837+
ECDSA_SIG* release();
838+
839+
static ECDSASigPointer New();
840+
static ECDSASigPointer Parse(const Buffer<const unsigned char>& buffer);
841+
842+
inline const BIGNUM* r() const { return pr_; }
843+
inline const BIGNUM* s() const { return ps_; }
844+
845+
bool setParams(BignumPointer&& r, BignumPointer&& s);
846+
847+
Buffer<unsigned char> encode() const;
848+
849+
private:
850+
DeleteFnPtr<ECDSA_SIG, ECDSA_SIG_free> sig_;
851+
const BIGNUM* pr_ = nullptr;
852+
const BIGNUM* ps_ = nullptr;
853+
};
854+
824855
#ifndef OPENSSL_NO_ENGINE
825856
class EnginePointer final {
826857
public:

src/crypto/crypto_sig.cc

+13-17
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,16 @@ bool ExtractP1363(
150150
unsigned char* out,
151151
size_t len,
152152
size_t n) {
153-
ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, len));
153+
ncrypto::Buffer<const unsigned char> sig_buffer{
154+
.data = sig_data,
155+
.len = len,
156+
};
157+
auto asn1_sig = ECDSASigPointer::Parse(sig_buffer);
154158
if (!asn1_sig)
155159
return false;
156160

157-
const BIGNUM* pr;
158-
const BIGNUM* ps;
159-
ECDSA_SIG_get0(asn1_sig.get(), &pr, &ps);
160-
161-
return BignumPointer::EncodePaddedInto(pr, out, n) > 0 &&
162-
BignumPointer::EncodePaddedInto(ps, out + n, n) > 0;
161+
return BignumPointer::EncodePaddedInto(asn1_sig.r(), out, n) > 0 &&
162+
BignumPointer::EncodePaddedInto(asn1_sig.s(), out + n, n) > 0;
163163
}
164164

165165
// Returns the maximum size of each of the integers (r, s) of the DSA signature.
@@ -213,23 +213,19 @@ ByteSource ConvertSignatureToDER(const EVPKeyPointer& pkey, ByteSource&& out) {
213213
if (out.size() != 2 * n)
214214
return ByteSource();
215215

216-
ECDSASigPointer asn1_sig(ECDSA_SIG_new());
216+
auto asn1_sig = ECDSASigPointer::New();
217217
CHECK(asn1_sig);
218218
BignumPointer r(sig_data, n);
219219
CHECK(r);
220220
BignumPointer s(sig_data + n, n);
221221
CHECK(s);
222-
CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r.release(), s.release()));
223-
224-
unsigned char* data = nullptr;
225-
int len = i2d_ECDSA_SIG(asn1_sig.get(), &data);
226-
227-
if (len <= 0)
228-
return ByteSource();
222+
CHECK(asn1_sig.setParams(std::move(r), std::move(s)));
229223

230-
CHECK_NOT_NULL(data);
224+
auto buf = asn1_sig.encode();
225+
if (buf.len <= 0) return ByteSource();
231226

232-
return ByteSource::Allocated(data, len);
227+
CHECK_NOT_NULL(buf.data);
228+
return ByteSource::Allocated(buf);
233229
}
234230

235231
void CheckThrow(Environment* env, SignBase::Error error) {

test/cctest/test_node_crypto_env.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
#include <ncrypto.h>
12
#include "crypto/crypto_bio.h"
23
#include "gtest/gtest.h"
34
#include "node_options.h"
45
#include "node_test_fixture.h"
56
#include "openssl/err.h"
6-
#include <ncrypto.h>
77

88
using v8::Local;
99
using v8::String;

0 commit comments

Comments
 (0)