Skip to content

Commit

Permalink
src: update ECKeyPointer in ncrypto
Browse files Browse the repository at this point in the history
  • Loading branch information
jasnell committed Jan 9, 2025
1 parent 1f5f2f4 commit 48cab6e
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 73 deletions.
120 changes: 120 additions & 0 deletions deps/ncrypto/ncrypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1790,6 +1790,21 @@ BIOPointer EVPKeyPointer::derPublicKey() const {
return bio;
}

bool EVPKeyPointer::assign(const ECKeyPointer& eckey) {
if (!pkey_ || !eckey) return {};
return EVP_PKEY_assign_EC_KEY(pkey_.get(), eckey.get());
}

bool EVPKeyPointer::set(const ECKeyPointer& eckey) {
if (!pkey_ || !eckey) return false;
return EVP_PKEY_set1_EC_KEY(pkey_.get(), eckey);
}

EVPKeyPointer::operator const EC_KEY*() const {
if (!pkey_) return nullptr;
return EVP_PKEY_get0_EC_KEY(pkey_.get());
}

namespace {
EVPKeyPointer::ParseKeyResult TryParsePublicKeyInner(const BIOPointer& bp,
const char* name,
Expand Down Expand Up @@ -2749,4 +2764,109 @@ bool ECPointPointer::mul(const EC_GROUP* group, const BIGNUM* priv_key) {
return EC_POINT_mul(group, point_.get(), priv_key, nullptr, nullptr, nullptr);
}

// ============================================================================

ECKeyPointer::ECKeyPointer() : key_(nullptr) {}

ECKeyPointer::ECKeyPointer(EC_KEY* key) : key_(key) {}

ECKeyPointer::ECKeyPointer(ECKeyPointer&& other) noexcept
: key_(other.release()) {}

ECKeyPointer& ECKeyPointer::operator=(ECKeyPointer&& other) noexcept {
key_.reset(other.release());
return *this;
}

ECKeyPointer::~ECKeyPointer() {
reset();
}

void ECKeyPointer::reset(EC_KEY* key) {
key_.reset(key);
}

EC_KEY* ECKeyPointer::release() {
return key_.release();
}

ECKeyPointer ECKeyPointer::clone() const {
if (!key_) return {};
return ECKeyPointer(EC_KEY_dup(key_.get()));
}

bool ECKeyPointer::generate() {
if (!key_) return false;
return EC_KEY_generate_key(key_.get());
}

bool ECKeyPointer::setPublicKey(const ECPointPointer& pub) {
if (!key_) return false;
return EC_KEY_set_public_key(key_.get(), pub.get()) == 1;
}

bool ECKeyPointer::setPublicKeyRaw(const BignumPointer& x,
const BignumPointer& y) {
if (!key_) return false;
return EC_KEY_set_public_key_affine_coordinates(
key_.get(), x.get(), y.get()) == 1;
}

bool ECKeyPointer::setPrivateKey(const BignumPointer& priv) {
if (!key_) return false;
return EC_KEY_set_private_key(key_.get(), priv.get()) == 1;
}

const BIGNUM* ECKeyPointer::getPrivateKey() const {
if (!key_) return nullptr;
return GetPrivateKey(key_.get());
}

const BIGNUM* ECKeyPointer::GetPrivateKey(const EC_KEY* key) {
return EC_KEY_get0_private_key(key);
}

const EC_POINT* ECKeyPointer::getPublicKey() const {
if (!key_) return nullptr;
return GetPublicKey(key_.get());
}

const EC_POINT* ECKeyPointer::GetPublicKey(const EC_KEY* key) {
return EC_KEY_get0_public_key(key);
}

const EC_GROUP* ECKeyPointer::getGroup() const {
if (!key_) return nullptr;
return GetGroup(key_.get());
}

const EC_GROUP* ECKeyPointer::GetGroup(const EC_KEY* key) {
return EC_KEY_get0_group(key);
}

int ECKeyPointer::GetGroupName(const EC_KEY* key) {
const EC_GROUP* group = GetGroup(key);
return group ? EC_GROUP_get_curve_name(group) : 0;
}

bool ECKeyPointer::Check(const EC_KEY* key) {
return EC_KEY_check_key(key) == 1;
}

bool ECKeyPointer::checkKey() const {
if (!key_) return false;
return Check(key_.get());
}

ECKeyPointer ECKeyPointer::NewByCurveName(int nid) {
return ECKeyPointer(EC_KEY_new_by_curve_name(nid));
}

ECKeyPointer ECKeyPointer::New(const EC_GROUP* group) {
auto ptr = ECKeyPointer(EC_KEY_new());
if (!ptr) return {};
if (!EC_KEY_set_group(ptr.get(), group)) return {};
return ptr;
}

} // namespace ncrypto
52 changes: 51 additions & 1 deletion deps/ncrypto/ncrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
#include <openssl/fips.h>
#endif // OPENSSL_FIPS

#if OPENSSL_VERSION_MAJOR >= 3
#define OSSL3_CONST const
#else
#define OSSL3_CONST
#endif

#ifdef __GNUC__
#define NCRYPTO_MUST_USE_RESULT __attribute__((warn_unused_result))
#else
Expand Down Expand Up @@ -197,7 +203,6 @@ using DeleteFnPtr = typename FunctionDeleter<T, function>::Pointer;

using BignumCtxPointer = DeleteFnPtr<BN_CTX, BN_CTX_free>;
using BignumGenCallbackPointer = DeleteFnPtr<BN_GENCB, BN_GENCB_free>;
using ECKeyPointer = DeleteFnPtr<EC_KEY, EC_KEY_free>;
using EVPKeyCtxPointer = DeleteFnPtr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
using EVPMDCtxPointer = DeleteFnPtr<EVP_MD_CTX, EVP_MD_CTX_free>;
using HMACCtxPointer = DeleteFnPtr<HMAC_CTX, HMAC_CTX_free>;
Expand All @@ -207,6 +212,7 @@ using RSAPointer = DeleteFnPtr<RSA, RSA_free>;
using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>;

class CipherCtxPointer;
class ECKeyPointer;

struct StackOfXASN1Deleter {
void operator()(STACK_OF(ASN1_OBJECT) * p) const {
Expand Down Expand Up @@ -537,6 +543,10 @@ class EVPKeyPointer final {
NCRYPTO_DISALLOW_COPY(EVPKeyPointer)
~EVPKeyPointer();

bool assign(const ECKeyPointer& eckey);
bool set(const ECKeyPointer& eckey);
operator const EC_KEY*() const;

inline bool operator==(std::nullptr_t) const noexcept {
return pkey_ == nullptr;
}
Expand Down Expand Up @@ -898,6 +908,46 @@ class ECPointPointer final {
DeleteFnPtr<EC_POINT, EC_POINT_free> point_;
};

class ECKeyPointer final {
public:
ECKeyPointer();
explicit ECKeyPointer(EC_KEY* key);
ECKeyPointer(ECKeyPointer&& other) noexcept;
ECKeyPointer& operator=(ECKeyPointer&& other) noexcept;
NCRYPTO_DISALLOW_COPY(ECKeyPointer)
~ECKeyPointer();

inline bool operator==(std::nullptr_t) noexcept { return key_ == nullptr; }
inline operator bool() const { return key_ != nullptr; }
inline EC_KEY* get() const { return key_.get(); }
inline operator EC_KEY*() const { return key_.get(); }
void reset(EC_KEY* key = nullptr);
EC_KEY* release();

ECKeyPointer clone() const;
bool setPrivateKey(const BignumPointer& priv);
bool setPublicKey(const ECPointPointer& pub);
bool setPublicKeyRaw(const BignumPointer& x, const BignumPointer& y);
bool generate();
bool checkKey() const;

const EC_GROUP* getGroup() const;
const BIGNUM* getPrivateKey() const;
const EC_POINT* getPublicKey() const;

static ECKeyPointer New(const EC_GROUP* group);
static ECKeyPointer NewByCurveName(int nid);

static const EC_POINT* GetPublicKey(const EC_KEY* key);
static const BIGNUM* GetPrivateKey(const EC_KEY* key);
static const EC_GROUP* GetGroup(const EC_KEY* key);
static int GetGroupName(const EC_KEY* key);
static bool Check(const EC_KEY* key);

private:
DeleteFnPtr<EC_KEY, EC_KEY_free> key_;
};

#ifndef OPENSSL_NO_ENGINE
class EnginePointer final {
public:
Expand Down
4 changes: 2 additions & 2 deletions src/crypto/crypto_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
namespace node {

using ncrypto::ClearErrorOnReturn;
using ncrypto::ECKeyPointer;
using ncrypto::EVPKeyPointer;
using ncrypto::SSLPointer;
using ncrypto::SSLSessionPointer;
Expand Down Expand Up @@ -271,8 +272,7 @@ MaybeLocal<Object> GetEphemeralKey(Environment* env, const SSLPointer& ssl) {
{
const char* curve_name;
if (kid == EVP_PKEY_EC) {
OSSL3_CONST EC_KEY* ec = EVP_PKEY_get0_EC_KEY(key.get());
int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
int nid = ECKeyPointer::GetGroupName(key);
curve_name = OBJ_nid2sn(nid);
} else {
curve_name = OBJ_nid2sn(kid);
Expand Down
8 changes: 0 additions & 8 deletions src/crypto/crypto_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@

#include <string>

// Some OpenSSL 1.1.1 functions unnecessarily operate on and return non-const
// pointers, whereas the same functions in OpenSSL 3 use const pointers.
#if OPENSSL_VERSION_MAJOR >= 3
#define OSSL3_CONST const
#else
#define OSSL3_CONST
#endif

namespace node {
namespace crypto {

Expand Down
Loading

0 comments on commit 48cab6e

Please sign in to comment.