diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index ebdda72184b709..8faa24566b17b6 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -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, @@ -2613,4 +2628,245 @@ bool CipherCtxPointer::getAeadTag(size_t len, unsigned char* out) { return EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG, len, out); } +// ============================================================================ + +ECDSASigPointer::ECDSASigPointer() : sig_(nullptr) {} +ECDSASigPointer::ECDSASigPointer(ECDSA_SIG* sig) : sig_(sig) { + if (sig_) { + ECDSA_SIG_get0(sig_.get(), &pr_, &ps_); + } +} +ECDSASigPointer::ECDSASigPointer(ECDSASigPointer&& other) noexcept + : sig_(other.release()) { + if (sig_) { + ECDSA_SIG_get0(sig_.get(), &pr_, &ps_); + } +} + +ECDSASigPointer& ECDSASigPointer::operator=(ECDSASigPointer&& other) noexcept { + sig_.reset(other.release()); + if (sig_) { + ECDSA_SIG_get0(sig_.get(), &pr_, &ps_); + } + return *this; +} + +ECDSASigPointer::~ECDSASigPointer() { + reset(); +} + +void ECDSASigPointer::reset(ECDSA_SIG* sig) { + sig_.reset(); + pr_ = nullptr; + ps_ = nullptr; +} + +ECDSA_SIG* ECDSASigPointer::release() { + pr_ = nullptr; + ps_ = nullptr; + return sig_.release(); +} + +ECDSASigPointer ECDSASigPointer::New() { + return ECDSASigPointer(ECDSA_SIG_new()); +} + +ECDSASigPointer ECDSASigPointer::Parse(const Buffer& sig) { + const unsigned char* ptr = sig.data; + return ECDSASigPointer(d2i_ECDSA_SIG(nullptr, &ptr, sig.len)); +} + +bool ECDSASigPointer::setParams(BignumPointer&& r, BignumPointer&& s) { + if (!sig_) return false; + return ECDSA_SIG_set0(sig_.get(), r.release(), s.release()); +} + +Buffer ECDSASigPointer::encode() const { + if (!sig_) + return { + .data = nullptr, + .len = 0, + }; + Buffer buf; + buf.len = i2d_ECDSA_SIG(sig_.get(), &buf.data); + return buf; +} + +// ============================================================================ + +ECGroupPointer::ECGroupPointer() : group_(nullptr) {} + +ECGroupPointer::ECGroupPointer(EC_GROUP* group) : group_(group) {} + +ECGroupPointer::ECGroupPointer(ECGroupPointer&& other) noexcept + : group_(other.release()) {} + +ECGroupPointer& ECGroupPointer::operator=(ECGroupPointer&& other) noexcept { + group_.reset(other.release()); + return *this; +} + +ECGroupPointer::~ECGroupPointer() { + reset(); +} + +void ECGroupPointer::reset(EC_GROUP* group) { + group_.reset(); +} + +EC_GROUP* ECGroupPointer::release() { + return group_.release(); +} + +ECGroupPointer ECGroupPointer::NewByCurveName(int nid) { + return ECGroupPointer(EC_GROUP_new_by_curve_name(nid)); +} + +// ============================================================================ + +ECPointPointer::ECPointPointer() : point_(nullptr) {} + +ECPointPointer::ECPointPointer(EC_POINT* point) : point_(point) {} + +ECPointPointer::ECPointPointer(ECPointPointer&& other) noexcept + : point_(other.release()) {} + +ECPointPointer& ECPointPointer::operator=(ECPointPointer&& other) noexcept { + point_.reset(other.release()); + return *this; +} + +ECPointPointer::~ECPointPointer() { + reset(); +} + +void ECPointPointer::reset(EC_POINT* point) { + point_.reset(point); +} + +EC_POINT* ECPointPointer::release() { + return point_.release(); +} + +ECPointPointer ECPointPointer::New(const EC_GROUP* group) { + return ECPointPointer(EC_POINT_new(group)); +} + +bool ECPointPointer::setFromBuffer(const Buffer& buffer, + const EC_GROUP* group) { + if (!point_) return false; + return EC_POINT_oct2point( + group, point_.get(), buffer.data, buffer.len, nullptr); +} + +bool ECPointPointer::mul(const EC_GROUP* group, const BIGNUM* priv_key) { + if (!point_) return false; + 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 diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index c718ae404dd223..e5bf2b529bf239 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -28,6 +28,12 @@ #include #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 @@ -197,13 +203,6 @@ using DeleteFnPtr = typename FunctionDeleter::Pointer; using BignumCtxPointer = DeleteFnPtr; using BignumGenCallbackPointer = DeleteFnPtr; -using DSAPointer = DeleteFnPtr; -using DSASigPointer = DeleteFnPtr; -using ECDSASigPointer = DeleteFnPtr; -using ECPointer = DeleteFnPtr; -using ECGroupPointer = DeleteFnPtr; -using ECKeyPointer = DeleteFnPtr; -using ECPointPointer = DeleteFnPtr; using EVPKeyCtxPointer = DeleteFnPtr; using EVPMDCtxPointer = DeleteFnPtr; using HMACCtxPointer = DeleteFnPtr; @@ -213,6 +212,7 @@ using RSAPointer = DeleteFnPtr; using SSLSessionPointer = DeleteFnPtr; class CipherCtxPointer; +class ECKeyPointer; struct StackOfXASN1Deleter { void operator()(STACK_OF(ASN1_OBJECT) * p) const { @@ -543,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; } @@ -824,6 +828,126 @@ class X509Pointer final { DeleteFnPtr cert_; }; +class ECDSASigPointer final { + public: + explicit ECDSASigPointer(); + explicit ECDSASigPointer(ECDSA_SIG* sig); + ECDSASigPointer(ECDSASigPointer&& other) noexcept; + ECDSASigPointer& operator=(ECDSASigPointer&& other) noexcept; + NCRYPTO_DISALLOW_COPY(ECDSASigPointer) + ~ECDSASigPointer(); + + inline bool operator==(std::nullptr_t) noexcept { return sig_ == nullptr; } + inline operator bool() const { return sig_ != nullptr; } + inline ECDSA_SIG* get() const { return sig_.get(); } + inline operator ECDSA_SIG*() const { return sig_.get(); } + void reset(ECDSA_SIG* sig = nullptr); + ECDSA_SIG* release(); + + static ECDSASigPointer New(); + static ECDSASigPointer Parse(const Buffer& buffer); + + inline const BIGNUM* r() const { return pr_; } + inline const BIGNUM* s() const { return ps_; } + + bool setParams(BignumPointer&& r, BignumPointer&& s); + + Buffer encode() const; + + private: + DeleteFnPtr sig_; + const BIGNUM* pr_ = nullptr; + const BIGNUM* ps_ = nullptr; +}; + +class ECGroupPointer final { + public: + explicit ECGroupPointer(); + explicit ECGroupPointer(EC_GROUP* group); + ECGroupPointer(ECGroupPointer&& other) noexcept; + ECGroupPointer& operator=(ECGroupPointer&& other) noexcept; + NCRYPTO_DISALLOW_COPY(ECGroupPointer) + ~ECGroupPointer(); + + inline bool operator==(std::nullptr_t) noexcept { return group_ == nullptr; } + inline operator bool() const { return group_ != nullptr; } + inline EC_GROUP* get() const { return group_.get(); } + inline operator EC_GROUP*() const { return group_.get(); } + void reset(EC_GROUP* group = nullptr); + EC_GROUP* release(); + + static ECGroupPointer NewByCurveName(int nid); + + private: + DeleteFnPtr group_; +}; + +class ECPointPointer final { + public: + ECPointPointer(); + explicit ECPointPointer(EC_POINT* point); + ECPointPointer(ECPointPointer&& other) noexcept; + ECPointPointer& operator=(ECPointPointer&& other) noexcept; + NCRYPTO_DISALLOW_COPY(ECPointPointer) + ~ECPointPointer(); + + inline bool operator==(std::nullptr_t) noexcept { return point_ == nullptr; } + inline operator bool() const { return point_ != nullptr; } + inline EC_POINT* get() const { return point_.get(); } + inline operator EC_POINT*() const { return point_.get(); } + void reset(EC_POINT* point = nullptr); + EC_POINT* release(); + + bool setFromBuffer(const Buffer& buffer, + const EC_GROUP* group); + bool mul(const EC_GROUP* group, const BIGNUM* priv_key); + + static ECPointPointer New(const EC_GROUP* group); + + private: + DeleteFnPtr 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 key_; +}; + #ifndef OPENSSL_NO_ENGINE class EnginePointer final { public: diff --git a/src/crypto/crypto_aes.cc b/src/crypto/crypto_aes.cc index 698f3574e47c3b..ce32b578f9b24a 100644 --- a/src/crypto/crypto_aes.cc +++ b/src/crypto/crypto_aes.cc @@ -16,6 +16,9 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::Cipher; +using ncrypto::CipherCtxPointer; using v8::FunctionCallbackInfo; using v8::Just; using v8::JustVoid; @@ -60,7 +63,7 @@ WebCryptoCipherStatus AES_Cipher(Environment* env, if (!ctx.setKeyLength(key_data.GetSymmetricKeySize()) || !ctx.init( - ncrypto::Cipher(), + Cipher(), encrypt, reinterpret_cast(key_data.GetSymmetricKey()), params.iv.data())) { @@ -464,7 +467,7 @@ Maybe AESCipherTraits::AdditionalConfig( } #undef V - params->cipher = ncrypto::Cipher::FromNid(cipher_nid); + params->cipher = Cipher::FromNid(cipher_nid); if (!params->cipher) { THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env); return Nothing(); diff --git a/src/crypto/crypto_bio.cc b/src/crypto/crypto_bio.cc index e9c920ccffa70a..f32cb1cff7d41d 100644 --- a/src/crypto/crypto_bio.cc +++ b/src/crypto/crypto_bio.cc @@ -30,6 +30,9 @@ #include namespace node { + +using ncrypto::BIOPointer; + namespace crypto { BIOPointer NodeBIO::New(Environment* env) { diff --git a/src/crypto/crypto_bio.h b/src/crypto/crypto_bio.h index 7587a353f11cde..d621d611f748f8 100644 --- a/src/crypto/crypto_bio.h +++ b/src/crypto/crypto_bio.h @@ -43,12 +43,13 @@ class NodeBIO : public MemoryRetainer { public: ~NodeBIO() override; - static BIOPointer New(Environment* env = nullptr); + static ncrypto::BIOPointer New(Environment* env = nullptr); // NewFixed takes a copy of `len` bytes from `data` and returns a BIO that, // when read from, returns those bytes followed by EOF. - static BIOPointer NewFixed(const char* data, size_t len, - Environment* env = nullptr); + static ncrypto::BIOPointer NewFixed(const char* data, + size_t len, + Environment* env = nullptr); // Move read head to next buffer if needed void TryMoveReadHead(); diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 8d8914058fc06c..61dd1e97d9672a 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -10,6 +10,13 @@ namespace node { +using ncrypto::Cipher; +using ncrypto::CipherCtxPointer; +using ncrypto::EVPKeyCtxPointer; +using ncrypto::EVPKeyPointer; +using ncrypto::MarkPopErrorOnReturn; +using ncrypto::SSLCtxPointer; +using ncrypto::SSLPointer; using v8::Array; using v8::ArrayBuffer; using v8::BackingStore; @@ -42,10 +49,10 @@ void GetCipherInfo(const FunctionCallbackInfo& args) { const auto cipher = ([&] { if (args[1]->IsString()) { Utf8Value name(env->isolate(), args[1]); - return ncrypto::Cipher::FromName(*name); + return Cipher::FromName(*name); } else { int nid = args[1].As()->Value(); - return ncrypto::Cipher::FromNid(nid); + return Cipher::FromNid(nid); } })(); @@ -334,7 +341,7 @@ void CipherBase::CommonInit(const char* cipher_type, return THROW_ERR_CRYPTO_INVALID_KEYLEN(env()); } - if (!ctx_.init(ncrypto::Cipher(), encrypt, key, iv)) { + if (!ctx_.init(Cipher(), encrypt, key, iv)) { return ThrowCryptoError(env(), ERR_get_error(), "Failed to initialize cipher"); } @@ -345,7 +352,7 @@ void CipherBase::Init(const char* cipher_type, unsigned int auth_tag_len) { HandleScope scope(env()->isolate()); MarkPopErrorOnReturn mark_pop_error_on_return; - auto cipher = ncrypto::Cipher::FromName(cipher_type); + auto cipher = Cipher::FromName(cipher_type); if (!cipher) { return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env()); } @@ -415,7 +422,7 @@ void CipherBase::InitIv(const char* cipher_type, HandleScope scope(env()->isolate()); MarkPopErrorOnReturn mark_pop_error_on_return; - auto cipher = ncrypto::Cipher::FromName(cipher_type); + auto cipher = Cipher::FromName(cipher_type); if (!cipher) return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env()); const int expected_iv_len = cipher.getIvLength(); @@ -628,8 +635,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo& args) { } else { // At this point, the tag length is already known and must match the // length of the given authentication tag. - CHECK( - ncrypto::Cipher::FromCtx(cipher->ctx_).isSupportedAuthenticatedMode()); + CHECK(Cipher::FromCtx(cipher->ctx_).isSupportedAuthenticatedMode()); CHECK_NE(cipher->auth_tag_len_, kNoAuthTagLength); is_valid = cipher->auth_tag_len_ == tag_len; } @@ -854,7 +860,7 @@ bool CipherBase::Final(std::unique_ptr* out) { } if (kind_ == kDecipher && - ncrypto::Cipher::FromCtx(ctx_).isSupportedAuthenticatedMode()) { + Cipher::FromCtx(ctx_).isSupportedAuthenticatedMode()) { MaybePassAuthTagToOpenSSL(); } diff --git a/src/crypto/crypto_cipher.h b/src/crypto/crypto_cipher.h index d15a231475d657..57c424e7509fa2 100644 --- a/src/crypto/crypto_cipher.h +++ b/src/crypto/crypto_cipher.h @@ -85,7 +85,7 @@ class CipherBase : public BaseObject { CipherBase(Environment* env, v8::Local wrap, CipherKind kind); private: - CipherCtxPointer ctx_; + ncrypto::CipherCtxPointer ctx_; const CipherKind kind_; AuthTagState auth_tag_state_; unsigned int auth_tag_len_; @@ -110,7 +110,7 @@ class PublicKeyCipher { EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init, EVP_PKEY_cipher_t EVP_PKEY_cipher> static bool Cipher(Environment* env, - const EVPKeyPointer& pkey, + const ncrypto::EVPKeyPointer& pkey, int padding, const EVP_MD* digest, const ArrayBufferOrViewContents& oaep_label, diff --git a/src/crypto/crypto_common.cc b/src/crypto/crypto_common.cc index 8ea34fe78b2592..d94f6e1c82c4a6 100644 --- a/src/crypto/crypto_common.cc +++ b/src/crypto/crypto_common.cc @@ -27,7 +27,14 @@ namespace node { +using ncrypto::ClearErrorOnReturn; +using ncrypto::ECKeyPointer; +using ncrypto::EVPKeyPointer; +using ncrypto::SSLPointer; +using ncrypto::SSLSessionPointer; using ncrypto::StackOfX509; +using ncrypto::X509Pointer; +using ncrypto::X509View; using v8::ArrayBuffer; using v8::BackingStore; using v8::Context; @@ -135,7 +142,7 @@ MaybeLocal AddIssuerChainToObject(X509Pointer* cert, for (;;) { int i; for (i = 0; i < sk_X509_num(peer_certs.get()); i++) { - ncrypto::X509View ca(sk_X509_value(peer_certs.get(), i)); + X509View ca(sk_X509_value(peer_certs.get(), i)); if (!cert->view().isIssuedBy(ca)) continue; Local ca_info; @@ -243,7 +250,7 @@ MaybeLocal GetEphemeralKey(Environment* env, const SSLPointer& ssl) { EscapableHandleScope scope(env->isolate()); Local info = Object::New(env->isolate()); - crypto::EVPKeyPointer key = ssl.getPeerTempKey(); + EVPKeyPointer key = ssl.getPeerTempKey(); if (!key) return scope.Escape(info); Local context = env->context(); @@ -265,8 +272,7 @@ MaybeLocal 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); @@ -341,8 +347,8 @@ MaybeLocal GetPeerCert( if (cert) { return X509Certificate::toObject(env, cert.view()); } - return X509Certificate::toObject( - env, ncrypto::X509View(sk_X509_value(ssl_certs, 0))); + return X509Certificate::toObject(env, + X509View(sk_X509_value(ssl_certs, 0))); } StackOfX509 peer_certs = CloneSSLCerts(std::move(cert), ssl_certs); @@ -351,7 +357,7 @@ MaybeLocal GetPeerCert( // First and main certificate. Local result; - ncrypto::X509View first_cert(sk_X509_value(peer_certs.get(), 0)); + X509View first_cert(sk_X509_value(peer_certs.get(), 0)); CHECK(first_cert); if (!X509Certificate::toObject(env, first_cert).ToLocal(&result)) return {}; CHECK(result->IsObject()); diff --git a/src/crypto/crypto_common.h b/src/crypto/crypto_common.h index bce577ade78b58..dba1cc14b1c486 100644 --- a/src/crypto/crypto_common.h +++ b/src/crypto/crypto_common.h @@ -11,24 +11,18 @@ #include -// 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 { -SSLSessionPointer GetTLSSession(const unsigned char* buf, size_t length); +ncrypto::SSLSessionPointer GetTLSSession(const unsigned char* buf, + size_t length); long VerifyPeerCertificate( // NOLINT(runtime/int) - const SSLPointer& ssl, + const ncrypto::SSLPointer& ssl, long def = X509_V_ERR_UNSPECIFIED); // NOLINT(runtime/int) -bool UseSNIContext(const SSLPointer& ssl, BaseObjectPtr context); +bool UseSNIContext(const ncrypto::SSLPointer& ssl, + BaseObjectPtr context); bool SetGroups(SecureContext* sc, const char* groups); @@ -36,21 +30,19 @@ v8::MaybeLocal GetValidationErrorReason(Environment* env, int err); v8::MaybeLocal GetValidationErrorCode(Environment* env, int err); -v8::MaybeLocal GetCert(Environment* env, const SSLPointer& ssl); +v8::MaybeLocal GetCert(Environment* env, + const ncrypto::SSLPointer& ssl); -v8::MaybeLocal GetCipherInfo( - Environment* env, - const SSLPointer& ssl); +v8::MaybeLocal GetCipherInfo(Environment* env, + const ncrypto::SSLPointer& ssl); -v8::MaybeLocal GetEphemeralKey( - Environment* env, - const SSLPointer& ssl); +v8::MaybeLocal GetEphemeralKey(Environment* env, + const ncrypto::SSLPointer& ssl); -v8::MaybeLocal GetPeerCert( - Environment* env, - const SSLPointer& ssl, - bool abbreviated = false, - bool is_server = false); +v8::MaybeLocal GetPeerCert(Environment* env, + const ncrypto::SSLPointer& ssl, + bool abbreviated = false, + bool is_server = false); v8::MaybeLocal ECPointToBuffer( Environment* env, @@ -60,9 +52,9 @@ v8::MaybeLocal ECPointToBuffer( const char** error); v8::MaybeLocal GetCurrentCipherName(Environment* env, - const SSLPointer& ssl); -v8::MaybeLocal GetCurrentCipherVersion(Environment* env, - const SSLPointer& ssl); + const ncrypto::SSLPointer& ssl); +v8::MaybeLocal GetCurrentCipherVersion( + Environment* env, const ncrypto::SSLPointer& ssl); } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index fa96b8d7a51d46..8f1e6dc7110b11 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -21,7 +21,17 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::BIOPointer; +using ncrypto::ClearErrorOnReturn; +using ncrypto::CryptoErrorList; +using ncrypto::DHPointer; +using ncrypto::EnginePointer; +using ncrypto::EVPKeyPointer; +using ncrypto::MarkPopErrorOnReturn; +using ncrypto::SSLPointer; using ncrypto::StackOfX509; +using ncrypto::X509Pointer; using v8::Array; using v8::ArrayBufferView; using v8::Boolean; @@ -693,10 +703,10 @@ void SecureContext::SetEngineKey(const FunctionCallbackInfo& args) { "experimental permission model is enabled"); } - ncrypto::CryptoErrorList errors; + CryptoErrorList errors; Utf8Value engine_id(env->isolate(), args[1]); - auto engine = ncrypto::EnginePointer::getEngineByName( - engine_id.ToStringView(), &errors); + auto engine = + EnginePointer::getEngineByName(engine_id.ToStringView(), &errors); if (!engine) { Local exception; if (errors.empty()) { @@ -1205,10 +1215,10 @@ void SecureContext::SetClientCertEngine( "experimental permission model is enabled"); } - ncrypto::CryptoErrorList errors; + CryptoErrorList errors; const Utf8Value engine_id(env->isolate(), args[0]); - auto engine = ncrypto::EnginePointer::getEngineByName( - engine_id.ToStringView(), &errors); + auto engine = + EnginePointer::getEngineByName(engine_id.ToStringView(), &errors); if (!engine) { Local exception; if (errors.empty()) { diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h index 7ba6a5441300fc..b6801fc0b40708 100644 --- a/src/crypto/crypto_context.h +++ b/src/crypto/crypto_context.h @@ -23,7 +23,7 @@ X509_STORE* NewRootCertStore(); X509_STORE* GetOrCreateRootCertStore(); -BIOPointer LoadBIO(Environment* env, v8::Local v); +ncrypto::BIOPointer LoadBIO(Environment* env, v8::Local v); class SecureContext final : public BaseObject { public: @@ -41,27 +41,27 @@ class SecureContext final : public BaseObject { static void RegisterExternalReferences(ExternalReferenceRegistry* registry); static SecureContext* Create(Environment* env); - const SSLCtxPointer& ctx() const { return ctx_; } + const ncrypto::SSLCtxPointer& ctx() const { return ctx_; } // Non-const ctx() that allows for non-default initialization of // the SecureContext. - SSLCtxPointer& ctx() { return ctx_; } + ncrypto::SSLCtxPointer& ctx() { return ctx_; } - SSLPointer CreateSSL(); + ncrypto::SSLPointer CreateSSL(); void SetGetSessionCallback(GetSessionCb cb); void SetKeylogCallback(KeylogCb cb); void SetNewSessionCallback(NewSessionCb cb); void SetSelectSNIContextCallback(SelectSNIContextCb cb); - inline const X509Pointer& issuer() const { return issuer_; } - inline const X509Pointer& cert() const { return cert_; } + inline const ncrypto::X509Pointer& issuer() const { return issuer_; } + inline const ncrypto::X509Pointer& cert() const { return cert_; } - v8::Maybe AddCert(Environment* env, BIOPointer&& bio); - v8::Maybe SetCRL(Environment* env, const BIOPointer& bio); + v8::Maybe AddCert(Environment* env, ncrypto::BIOPointer&& bio); + v8::Maybe SetCRL(Environment* env, const ncrypto::BIOPointer& bio); v8::Maybe UseKey(Environment* env, const KeyObjectData& key); - void SetCACert(const BIOPointer& bio); + void SetCACert(const ncrypto::BIOPointer& bio); void SetRootCerts(); void SetX509StoreFlag(unsigned long flags); // NOLINT(runtime/int) @@ -144,9 +144,9 @@ class SecureContext final : public BaseObject { void Reset(); private: - SSLCtxPointer ctx_; - X509Pointer cert_; - X509Pointer issuer_; + ncrypto::SSLCtxPointer ctx_; + ncrypto::X509Pointer cert_; + ncrypto::X509Pointer issuer_; // Non-owning cache for SSL_CTX_get_cert_store(ctx_.get()) X509_STORE* own_cert_store_cache_ = nullptr; #ifndef OPENSSL_NO_ENGINE @@ -160,9 +160,9 @@ class SecureContext final : public BaseObject { }; int SSL_CTX_use_certificate_chain(SSL_CTX* ctx, - BIOPointer&& in, - X509Pointer* cert, - X509Pointer* issuer); + ncrypto::BIOPointer&& in, + ncrypto::X509Pointer* cert, + ncrypto::X509Pointer* issuer); } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index d760a0d3ea1d12..7041eb985d9f6d 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -14,6 +14,11 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::DataPointer; +using ncrypto::DHPointer; +using ncrypto::EVPKeyCtxPointer; +using ncrypto::EVPKeyPointer; using v8::ArrayBuffer; using v8::ConstructorBehavior; using v8::Context; @@ -47,14 +52,11 @@ void DiffieHellman::MemoryInfo(MemoryTracker* tracker) const { } namespace { -MaybeLocal DataPointerToBuffer(Environment* env, - ncrypto::DataPointer&& data) { +MaybeLocal DataPointerToBuffer(Environment* env, DataPointer&& data) { auto backing = ArrayBuffer::NewBackingStore( data.get(), data.size(), - [](void* data, size_t len, void* ptr) { - ncrypto::DataPointer free_ne(data, len); - }, + [](void* data, size_t len, void* ptr) { DataPointer free_me(data, len); }, nullptr); data.release(); diff --git a/src/crypto/crypto_dh.h b/src/crypto/crypto_dh.h index a84993ddd55f02..2af668035bbb0a 100644 --- a/src/crypto/crypto_dh.h +++ b/src/crypto/crypto_dh.h @@ -19,22 +19,24 @@ class DiffieHellman final : public BaseObject { static void Initialize(Environment* env, v8::Local target); static void RegisterExternalReferences(ExternalReferenceRegistry* registry); - DiffieHellman(Environment* env, v8::Local wrap, DHPointer dh); - operator DHPointer&() { return dh_; } + DiffieHellman(Environment* env, + v8::Local wrap, + ncrypto::DHPointer dh); + operator ncrypto::DHPointer&() { return dh_; } void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(DiffieHellman) SET_SELF_SIZE(DiffieHellman) private: - DHPointer dh_; + ncrypto::DHPointer dh_; }; struct DhKeyPairParams final : public MemoryRetainer { // Diffie-Hellman can either generate keys using a fixed prime, or by first // generating a random prime of a given size (in bits). Only one of both // options may be specified. - std::variant prime; + std::variant prime; unsigned int generator; SET_NO_MEMORY_INFO() SET_MEMORY_INFO_NAME(DhKeyPairParams) @@ -47,7 +49,7 @@ struct DhKeyGenTraits final { using AdditionalParameters = DhKeyPairGenConfig; static constexpr const char* JobName = "DhKeyPairGenJob"; - static EVPKeyCtxPointer Setup(DhKeyPairGenConfig* params); + static ncrypto::EVPKeyCtxPointer Setup(DhKeyPairGenConfig* params); static v8::Maybe AdditionalConfig( CryptoJobMode mode, diff --git a/src/crypto/crypto_dsa.cc b/src/crypto/crypto_dsa.cc index b557de774117e4..471fee77531139 100644 --- a/src/crypto/crypto_dsa.cc +++ b/src/crypto/crypto_dsa.cc @@ -25,6 +25,9 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::EVPKeyCtxPointer; +using ncrypto::EVPKeyPointer; using v8::FunctionCallbackInfo; using v8::Int32; using v8::JustVoid; diff --git a/src/crypto/crypto_dsa.h b/src/crypto/crypto_dsa.h index fab167038c8862..c31aa9786558c2 100644 --- a/src/crypto/crypto_dsa.h +++ b/src/crypto/crypto_dsa.h @@ -26,7 +26,7 @@ struct DsaKeyGenTraits final { using AdditionalParameters = DsaKeyPairGenConfig; static constexpr const char* JobName = "DsaKeyPairGenJob"; - static EVPKeyCtxPointer Setup(DsaKeyPairGenConfig* params); + static ncrypto::EVPKeyCtxPointer Setup(DsaKeyPairGenConfig* params); static v8::Maybe AdditionalConfig( CryptoJobMode mode, diff --git a/src/crypto/crypto_ec.cc b/src/crypto/crypto_ec.cc index 9670f821ef97a6..5ccda6f0768873 100644 --- a/src/crypto/crypto_ec.cc +++ b/src/crypto/crypto_ec.cc @@ -18,6 +18,14 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::DataPointer; +using ncrypto::ECGroupPointer; +using ncrypto::ECKeyPointer; +using ncrypto::ECPointPointer; +using ncrypto::EVPKeyCtxPointer; +using ncrypto::EVPKeyPointer; +using ncrypto::MarkPopErrorOnReturn; using v8::Array; using v8::ArrayBuffer; using v8::BackingStore; @@ -104,9 +112,7 @@ void ECDH::GetCurves(const FunctionCallbackInfo& args) { } ECDH::ECDH(Environment* env, Local wrap, ECKeyPointer&& key) - : BaseObject(env, wrap), - key_(std::move(key)), - group_(EC_KEY_get0_group(key_.get())) { + : BaseObject(env, wrap), key_(std::move(key)), group_(key_.getGroup()) { MakeWeak(); CHECK_NOT_NULL(group_); } @@ -128,7 +134,7 @@ void ECDH::New(const FunctionCallbackInfo& args) { if (nid == NID_undef) return THROW_ERR_CRYPTO_INVALID_CURVE(env); - ECKeyPointer key(EC_KEY_new_by_curve_name(nid)); + auto key = ECKeyPointer::NewByCurveName(nid); if (!key) return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to create key using named curve"); @@ -142,35 +148,34 @@ void ECDH::GenerateKeys(const FunctionCallbackInfo& args) { ECDH* ecdh; ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This()); - if (!EC_KEY_generate_key(ecdh->key_.get())) + if (!ecdh->key_.generate()) { return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to generate key"); + } } ECPointPointer ECDH::BufferToPoint(Environment* env, const EC_GROUP* group, Local buf) { - int r; + ArrayBufferOrViewContents input(buf); + if (!input.CheckSizeInt32()) [[unlikely]] { + THROW_ERR_OUT_OF_RANGE(env, "buffer is too big"); + return {}; + } - ECPointPointer pub(EC_POINT_new(group)); + auto pub = ECPointPointer::New(group); if (!pub) { THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to allocate EC_POINT for a public key"); return pub; } - ArrayBufferOrViewContents input(buf); - if (!input.CheckSizeInt32()) [[unlikely]] { - THROW_ERR_OUT_OF_RANGE(env, "buffer is too big"); - return ECPointPointer(); + ncrypto::Buffer buffer{ + .data = input.data(), + .len = input.size(), + }; + if (!pub.setFromBuffer(buffer, group)) { + return {}; } - r = EC_POINT_oct2point( - group, - pub.get(), - input.data(), - input.size(), - nullptr); - if (!r) - return ECPointPointer(); return pub; } @@ -188,10 +193,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { if (!ecdh->IsKeyPairValid()) return THROW_ERR_CRYPTO_INVALID_KEYPAIR(env); - ECPointPointer pub( - ECDH::BufferToPoint(env, - ecdh->group_, - args[0])); + auto pub = ECDH::BufferToPoint(env, ecdh->group_, args[0]); if (!pub) { args.GetReturnValue().Set( FIXED_ONE_BYTE_STRING(env->isolate(), @@ -209,7 +211,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { } if (!ECDH_compute_key( - bs->Data(), bs->ByteLength(), pub.get(), ecdh->key_.get(), nullptr)) + bs->Data(), bs->ByteLength(), pub, ecdh->key_.get(), nullptr)) return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to compute ECDH key"); Local ab = ArrayBuffer::New(env->isolate(), std::move(bs)); @@ -227,8 +229,8 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo& args) { ECDH* ecdh; ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This()); - const EC_GROUP* group = EC_KEY_get0_group(ecdh->key_.get()); - const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_.get()); + const auto group = ecdh->key_.getGroup(); + const auto pub = ecdh->key_.getPublicKey(); if (pub == nullptr) return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to get ECDH public key"); @@ -250,7 +252,7 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo& args) { ECDH* ecdh; ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This()); - const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_.get()); + auto b = ecdh->key_.getPrivateKey(); if (b == nullptr) return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to get ECDH private key"); @@ -292,10 +294,10 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo& args) { "Private key is not valid for specified curve."); } - ECKeyPointer new_key(EC_KEY_dup(ecdh->key_.get())); + auto new_key = ecdh->key_.clone(); CHECK(new_key); - int result = EC_KEY_set_private_key(new_key.get(), priv.get()); + bool result = new_key.setPrivateKey(priv); priv.reset(); if (!result) { @@ -306,24 +308,24 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo& args) { MarkPopErrorOnReturn mark_pop_error_on_return; USE(&mark_pop_error_on_return); - const BIGNUM* priv_key = EC_KEY_get0_private_key(new_key.get()); + auto priv_key = new_key.getPrivateKey(); CHECK_NOT_NULL(priv_key); - ECPointPointer pub(EC_POINT_new(ecdh->group_)); + auto pub = ECPointPointer::New(ecdh->group_); CHECK(pub); - if (!EC_POINT_mul(ecdh->group_, pub.get(), priv_key, - nullptr, nullptr, nullptr)) { + if (!pub.mul(ecdh->group_, priv_key)) { return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to generate ECDH public key"); } - if (!EC_KEY_set_public_key(new_key.get(), pub.get())) + if (!new_key.setPublicKey(pub)) { return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to set generated public key"); + } ecdh->key_ = std::move(new_key); - ecdh->group_ = EC_KEY_get0_group(ecdh->key_.get()); + ecdh->group_ = ecdh->key_.getGroup(); } void ECDH::SetPublicKey(const FunctionCallbackInfo& args) { @@ -336,17 +338,13 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo& args) { MarkPopErrorOnReturn mark_pop_error_on_return; - ECPointPointer pub( - ECDH::BufferToPoint(env, - ecdh->group_, - args[0])); + auto pub = ECDH::BufferToPoint(env, ecdh->group_, args[0]); if (!pub) { return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to convert Buffer to EC_POINT"); } - int r = EC_KEY_set_public_key(ecdh->key_.get(), pub.get()); - if (!r) { + if (!ecdh->key_.setPublicKey(pub)) { return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to set EC_POINT as the public key"); } @@ -368,8 +366,7 @@ bool ECDH::IsKeyValidForCurve(const BignumPointer& private_key) { bool ECDH::IsKeyPairValid() { MarkPopErrorOnReturn mark_pop_error_on_return; - USE(&mark_pop_error_on_return); - return 1 == EC_KEY_check_key(key_.get()); + return key_.checkKey(); } // Convert the input public key to compressed, uncompressed, or hybrid formats. @@ -391,17 +388,12 @@ void ECDH::ConvertKey(const FunctionCallbackInfo& args) { if (nid == NID_undef) return THROW_ERR_CRYPTO_INVALID_CURVE(env); - ECGroupPointer group( - EC_GROUP_new_by_curve_name(nid)); - if (group == nullptr) + auto group = ECGroupPointer::NewByCurveName(nid); + if (!group) return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to get EC_GROUP"); - ECPointPointer pub( - ECDH::BufferToPoint(env, - group.get(), - args[0])); - - if (pub == nullptr) { + auto pub = ECDH::BufferToPoint(env, group, args[0]); + if (!pub) { return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to convert Buffer to EC_POINT"); } @@ -412,7 +404,7 @@ void ECDH::ConvertKey(const FunctionCallbackInfo& args) { const char* error; Local buf; - if (!ECPointToBuffer(env, group.get(), pub.get(), form, &error).ToLocal(&buf)) + if (!ECPointToBuffer(env, group, pub, form, &error).ToLocal(&buf)) return THROW_ERR_CRYPTO_OPERATION_FAILED(env, error); args.GetReturnValue().Set(buf); } @@ -491,19 +483,19 @@ bool ECDHBitsTraits::DeriveBits(Environment* env, const EC_KEY* private_key; { Mutex::ScopedLock priv_lock(params.private_.mutex()); - private_key = EVP_PKEY_get0_EC_KEY(m_privkey.get()); + private_key = m_privkey; } Mutex::ScopedLock pub_lock(params.public_.mutex()); - const EC_KEY* public_key = EVP_PKEY_get0_EC_KEY(m_pubkey.get()); + const EC_KEY* public_key = m_pubkey; - const EC_GROUP* group = EC_KEY_get0_group(private_key); + const auto group = ECKeyPointer::GetGroup(private_key); if (group == nullptr) return false; - CHECK_EQ(EC_KEY_check_key(private_key), 1); - CHECK_EQ(EC_KEY_check_key(public_key), 1); - const EC_POINT* pub = EC_KEY_get0_public_key(public_key); + CHECK(ECKeyPointer::Check(private_key)); + CHECK(ECKeyPointer::Check(public_key)); + const auto pub = ECKeyPointer::GetPublicKey(public_key); int field_size = EC_GROUP_get_degree(group); len = (field_size + 7) / 8; ByteSource::Builder buf(len); @@ -602,7 +594,7 @@ WebCryptoKeyExportStatus EC_Raw_Export(const KeyObjectData& key_data, CHECK(m_pkey); Mutex::ScopedLock lock(key_data.mutex()); - const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(m_pkey.get()); + const EC_KEY* ec_key = m_pkey; if (ec_key == nullptr) { switch (key_data.GetKeyType()) { @@ -624,8 +616,8 @@ WebCryptoKeyExportStatus EC_Raw_Export(const KeyObjectData& key_data, } else { if (key_data.GetKeyType() != kKeyTypePublic) return WebCryptoKeyExportStatus::INVALID_KEY_TYPE; - const EC_GROUP* group = EC_KEY_get0_group(ec_key); - const EC_POINT* point = EC_KEY_get0_public_key(ec_key); + const auto group = ECKeyPointer::GetGroup(ec_key); + const auto point = ECKeyPointer::GetPublicKey(ec_key); point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; // Get the allocated data size... @@ -681,9 +673,8 @@ WebCryptoKeyExportStatus ECKeyExportTraits::DoExport( // the header is for all practical purposes a static 26 byte sequence // where only the second byte changes. Mutex::ScopedLock lock(key_data.mutex()); - const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(m_pkey.get()); - const EC_GROUP* group = EC_KEY_get0_group(ec_key); - const EC_POINT* point = EC_KEY_get0_public_key(ec_key); + const auto group = ECKeyPointer::GetGroup(m_pkey); + const auto point = ECKeyPointer::GetPublicKey(m_pkey); const point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; const size_t need = EC_POINT_point2oct(group, point, form, nullptr, 0, nullptr); @@ -692,18 +683,17 @@ WebCryptoKeyExportStatus ECKeyExportTraits::DoExport( const size_t have = EC_POINT_point2oct( group, point, form, data.data(), need, nullptr); if (have == 0) return WebCryptoKeyExportStatus::FAILED; - ECKeyPointer ec(EC_KEY_new()); - CHECK_EQ(1, EC_KEY_set_group(ec.get(), group)); - ECPointPointer uncompressed(EC_POINT_new(group)); - CHECK_EQ(1, - EC_POINT_oct2point(group, - uncompressed.get(), - data.data(), - data.size(), - nullptr)); - CHECK_EQ(1, EC_KEY_set_public_key(ec.get(), uncompressed.get())); + auto ec = ECKeyPointer::New(group); + CHECK(ec); + auto uncompressed = ECPointPointer::New(group); + ncrypto::Buffer buffer{ + .data = data.data(), + .len = data.size(), + }; + CHECK(uncompressed.setFromBuffer(buffer, group)); + CHECK(ec.setPublicKey(uncompressed)); auto pkey = EVPKeyPointer::New(); - CHECK_EQ(1, EVP_PKEY_set1_EC_KEY(pkey.get(), ec.get())); + CHECK(pkey.set(ec)); auto bio = pkey.derPublicKey(); if (!bio) return WebCryptoKeyExportStatus::FAILED; *out = ByteSource::FromBIO(bio); @@ -722,11 +712,11 @@ Maybe ExportJWKEcKey(Environment* env, const auto& m_pkey = key.GetAsymmetricKey(); CHECK_EQ(m_pkey.id(), EVP_PKEY_EC); - const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(m_pkey.get()); + const EC_KEY* ec = m_pkey; CHECK_NOT_NULL(ec); - const EC_POINT* pub = EC_KEY_get0_public_key(ec); - const EC_GROUP* group = EC_KEY_get0_group(ec); + const auto pub = ECKeyPointer::GetPublicKey(ec); + const auto group = ECKeyPointer::GetGroup(ec); int degree_bits = EC_GROUP_get_degree(group); int degree_bytes = @@ -792,7 +782,7 @@ Maybe ExportJWKEcKey(Environment* env, } if (key.GetKeyType() == kKeyTypePrivate) { - const BIGNUM* pvt = EC_KEY_get0_private_key(ec); + auto pvt = ECKeyPointer::GetPrivateKey(ec); return SetEncodedValue(env, target, env->jwk_d_string(), pvt, degree_bytes); } @@ -821,7 +811,7 @@ Maybe ExportJWKEdKey(Environment* env, })(); static constexpr auto trySetKey = [](Environment* env, - ncrypto::DataPointer data, + DataPointer data, Local target, Local key) { Local encoded; @@ -886,7 +876,7 @@ KeyObjectData ImportJWKEcKey(Environment* env, KeyType type = d_value->IsString() ? kKeyTypePrivate : kKeyTypePublic; - ECKeyPointer ec(EC_KEY_new_by_curve_name(nid)); + auto ec = ECKeyPointer::NewByCurveName(nid); if (!ec) { THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK EC key"); return {}; @@ -895,24 +885,22 @@ KeyObjectData ImportJWKEcKey(Environment* env, ByteSource x = ByteSource::FromEncodedString(env, x_value.As()); ByteSource y = ByteSource::FromEncodedString(env, y_value.As()); - if (!EC_KEY_set_public_key_affine_coordinates( - ec.get(), - x.ToBN().get(), - y.ToBN().get())) { + if (!ec.setPublicKeyRaw(x.ToBN(), y.ToBN())) { THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK EC key"); return {}; } if (type == kKeyTypePrivate) { ByteSource d = ByteSource::FromEncodedString(env, d_value.As()); - if (!EC_KEY_set_private_key(ec.get(), d.ToBN().get())) { + if (!ec.setPrivateKey(d.ToBN())) { THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK EC key"); return {}; } } auto pkey = EVPKeyPointer::New(); - CHECK_EQ(EVP_PKEY_set1_EC_KEY(pkey.get(), ec.get()), 1); + if (!pkey) return {}; + CHECK(pkey.set(ec)); return KeyObjectData::CreateAsymmetric(type, std::move(pkey)); } @@ -924,10 +912,10 @@ Maybe GetEcKeyDetail(Environment* env, const auto& m_pkey = key.GetAsymmetricKey(); CHECK_EQ(m_pkey.id(), EVP_PKEY_EC); - const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(m_pkey.get()); + const EC_KEY* ec = m_pkey; CHECK_NOT_NULL(ec); - const EC_GROUP* group = EC_KEY_get0_group(ec); + const auto group = ECKeyPointer::GetGroup(ec); int nid = EC_GROUP_get_curve_name(group); if (target @@ -946,11 +934,10 @@ Maybe GetEcKeyDetail(Environment* env, // https://github.com/chromium/chromium/blob/7af6cfd/components/webcrypto/algorithms/ecdsa.cc size_t GroupOrderSize(const EVPKeyPointer& key) { - const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(key.get()); + const EC_KEY* ec = key; CHECK_NOT_NULL(ec); - const EC_GROUP* group = EC_KEY_get0_group(ec); auto order = BignumPointer::New(); - CHECK(EC_GROUP_get_order(group, order.get(), nullptr)); + CHECK(EC_GROUP_get_order(ECKeyPointer::GetGroup(ec), order.get(), nullptr)); return order.byteLength(); } } // namespace crypto diff --git a/src/crypto/crypto_ec.h b/src/crypto/crypto_ec.h index b5de681fbe1516..7aeeebbe303eda 100644 --- a/src/crypto/crypto_ec.h +++ b/src/crypto/crypto_ec.h @@ -24,9 +24,9 @@ class ECDH final : public BaseObject { static void Initialize(Environment* env, v8::Local target); static void RegisterExternalReferences(ExternalReferenceRegistry* registry); - static ECPointPointer BufferToPoint(Environment* env, - const EC_GROUP* group, - v8::Local buf); + static ncrypto::ECPointPointer BufferToPoint(Environment* env, + const EC_GROUP* group, + v8::Local buf); void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(ECDH) @@ -37,7 +37,9 @@ class ECDH final : public BaseObject { static void GetCurves(const v8::FunctionCallbackInfo& args); protected: - ECDH(Environment* env, v8::Local wrap, ECKeyPointer&& key); + ECDH(Environment* env, + v8::Local wrap, + ncrypto::ECKeyPointer&& key); static void New(const v8::FunctionCallbackInfo& args); static void GenerateKeys(const v8::FunctionCallbackInfo& args); @@ -48,9 +50,9 @@ class ECDH final : public BaseObject { static void SetPublicKey(const v8::FunctionCallbackInfo& args); bool IsKeyPairValid(); - bool IsKeyValidForCurve(const BignumPointer& private_key); + bool IsKeyValidForCurve(const ncrypto::BignumPointer& private_key); - ECKeyPointer key_; + ncrypto::ECKeyPointer key_; const EC_GROUP* group_; }; @@ -102,7 +104,7 @@ struct EcKeyGenTraits final { using AdditionalParameters = EcKeyPairGenConfig; static constexpr const char* JobName = "EcKeyPairGenJob"; - static EVPKeyCtxPointer Setup(EcKeyPairGenConfig* params); + static ncrypto::EVPKeyCtxPointer Setup(EcKeyPairGenConfig* params); static v8::Maybe AdditionalConfig( CryptoJobMode mode, diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index 58856397cdff92..bcd4c533b07ceb 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -11,6 +11,8 @@ namespace node { +using ncrypto::EVPMDCtxPointer; +using ncrypto::MarkPopErrorOnReturn; using v8::Context; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; diff --git a/src/crypto/crypto_hash.h b/src/crypto/crypto_hash.h index 4289c352a7cdae..85da86dba98d5a 100644 --- a/src/crypto/crypto_hash.h +++ b/src/crypto/crypto_hash.h @@ -36,7 +36,7 @@ class Hash final : public BaseObject { Hash(Environment* env, v8::Local wrap); private: - EVPMDCtxPointer mdctx_{}; + ncrypto::EVPMDCtxPointer mdctx_{}; unsigned int md_len_ = 0; ByteSource digest_; }; diff --git a/src/crypto/crypto_hmac.cc b/src/crypto/crypto_hmac.cc index ecc4f3fd8ae7df..25ccb1b9d04e51 100644 --- a/src/crypto/crypto_hmac.cc +++ b/src/crypto/crypto_hmac.cc @@ -13,6 +13,7 @@ namespace node { +using ncrypto::HMACCtxPointer; using v8::Boolean; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; diff --git a/src/crypto/crypto_hmac.h b/src/crypto/crypto_hmac.h index 2f54b1c8a14af6..e29ec231a1b7d4 100644 --- a/src/crypto/crypto_hmac.h +++ b/src/crypto/crypto_hmac.h @@ -36,7 +36,7 @@ class Hmac : public BaseObject { static void Sign(const v8::FunctionCallbackInfo& args); private: - HMACCtxPointer ctx_; + ncrypto::HMACCtxPointer ctx_; }; struct HmacConfig final : public MemoryRetainer { diff --git a/src/crypto/crypto_keygen.cc b/src/crypto/crypto_keygen.cc index c13acd63886673..246191f5d51796 100644 --- a/src/crypto/crypto_keygen.cc +++ b/src/crypto/crypto_keygen.cc @@ -12,6 +12,7 @@ namespace node { +using ncrypto::EVPKeyCtxPointer; using v8::FunctionCallbackInfo; using v8::Int32; using v8::JustVoid; diff --git a/src/crypto/crypto_keygen.h b/src/crypto/crypto_keygen.h index f1e92c69cb4065..6fdac8333b6ac6 100644 --- a/src/crypto/crypto_keygen.h +++ b/src/crypto/crypto_keygen.h @@ -163,7 +163,7 @@ struct KeyPairGenTraits final { static KeyGenJobStatus DoKeyGen( Environment* env, AdditionalParameters* params) { - EVPKeyCtxPointer ctx = KeyPairAlgorithmTraits::Setup(params); + ncrypto::EVPKeyCtxPointer ctx = KeyPairAlgorithmTraits::Setup(params); if (!ctx) return KeyGenJobStatus::FAILED; @@ -174,7 +174,7 @@ struct KeyPairGenTraits final { return KeyGenJobStatus::FAILED; auto data = KeyObjectData::CreateAsymmetric(KeyType::kKeyTypePrivate, - EVPKeyPointer(pkey)); + ncrypto::EVPKeyPointer(pkey)); if (!data) [[unlikely]] return KeyGenJobStatus::FAILED; params->key = std::move(data); @@ -280,7 +280,7 @@ struct NidKeyPairGenTraits final { using AdditionalParameters = NidKeyPairGenConfig; static constexpr const char* JobName = "NidKeyPairGenJob"; - static EVPKeyCtxPointer Setup(NidKeyPairGenConfig* params); + static ncrypto::EVPKeyCtxPointer Setup(NidKeyPairGenConfig* params); static v8::Maybe AdditionalConfig( CryptoJobMode mode, diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index 4a686a77b2a0ac..bedcf04d036478 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -18,6 +18,12 @@ namespace node { +using ncrypto::BIOPointer; +using ncrypto::ECKeyPointer; +using ncrypto::EVPKeyCtxPointer; +using ncrypto::EVPKeyPointer; +using ncrypto::MarkPopErrorOnReturn; +using ncrypto::PKCS8Pointer; using v8::Array; using v8::Context; using v8::Function; @@ -41,11 +47,11 @@ using v8::Value; namespace crypto { namespace { -Maybe -GetKeyFormatAndTypeFromJs(const FunctionCallbackInfo& args, - unsigned int* offset, - KeyEncodingContext context) { - ncrypto::EVPKeyPointer::AsymmetricKeyEncodingConfig config; +Maybe GetKeyFormatAndTypeFromJs( + const FunctionCallbackInfo& args, + unsigned int* offset, + KeyEncodingContext context) { + EVPKeyPointer::AsymmetricKeyEncodingConfig config; // During key pair generation, it is possible not to specify a key encoding, // which will lead to a key object being returned. if (args[*offset]->IsUndefined()) { @@ -56,19 +62,19 @@ GetKeyFormatAndTypeFromJs(const FunctionCallbackInfo& args, config.output_key_object = false; CHECK(args[*offset]->IsInt32()); - config.format = static_cast( + config.format = static_cast( args[*offset].As()->Value()); if (args[*offset + 1]->IsInt32()) { - config.type = static_cast( + config.type = static_cast( args[*offset + 1].As()->Value()); } else { CHECK((context == kKeyContextInput && - config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) || + config.format == EVPKeyPointer::PKFormatType::PEM) || (context == kKeyContextGenerate && - config.format == ncrypto::EVPKeyPointer::PKFormatType::JWK)); + config.format == EVPKeyPointer::PKFormatType::JWK)); CHECK(args[*offset + 1]->IsNullOrUndefined()); - config.type = ncrypto::EVPKeyPointer::PKEncodingType::PKCS1; + config.type = EVPKeyPointer::PKEncodingType::PKCS1; } } @@ -79,16 +85,16 @@ GetKeyFormatAndTypeFromJs(const FunctionCallbackInfo& args, MaybeLocal BIOToStringOrBuffer( Environment* env, const BIOPointer& bio, - const ncrypto::EVPKeyPointer::AsymmetricKeyEncodingConfig& config) { + const EVPKeyPointer::AsymmetricKeyEncodingConfig& config) { BUF_MEM* bptr = bio; - if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { + if (config.format == EVPKeyPointer::PKFormatType::PEM) { // PEM is an ASCII format, so we will return it as a string. return String::NewFromUtf8( env->isolate(), bptr->data, NewStringType::kNormal, bptr->length) .FromMaybe(Local()); } - CHECK_EQ(config.format, ncrypto::EVPKeyPointer::PKFormatType::DER); + CHECK_EQ(config.format, EVPKeyPointer::PKFormatType::DER); // DER is binary, return it as a buffer. return Buffer::Copy(env, bptr->data, bptr->length).FromMaybe(Local()); } @@ -96,7 +102,7 @@ MaybeLocal BIOToStringOrBuffer( MaybeLocal WritePrivateKey( Environment* env, const EVPKeyPointer& pkey, - const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config) { + const EVPKeyPointer::PrivateKeyEncodingConfig& config) { CHECK(pkey); auto res = pkey.writePrivateKey(config); if (res) { @@ -111,7 +117,7 @@ MaybeLocal WritePrivateKey( MaybeLocal WritePublicKey( Environment* env, const EVPKeyPointer& pkey, - const ncrypto::EVPKeyPointer::PublicKeyEncodingConfig& config) { + const EVPKeyPointer::PublicKeyEncodingConfig& config) { CHECK(pkey); auto res = pkey.writePublicKey(config); if (res) { @@ -243,7 +249,7 @@ Maybe GetAsymmetricKeyDetail(Environment* env, KeyObjectData TryParsePrivateKey( Environment* env, - const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config, + const EVPKeyPointer::PrivateKeyEncodingConfig& config, const ncrypto::Buffer& buffer) { auto res = EVPKeyPointer::TryParsePrivateKey(config, buffer); if (res) { @@ -285,7 +291,7 @@ Maybe ExportJWKInner(Environment* env, Maybe KeyObjectData::ToEncodedPublicKey( Environment* env, - const ncrypto::EVPKeyPointer::PublicKeyEncodingConfig& config, + const EVPKeyPointer::PublicKeyEncodingConfig& config, Local* out) { CHECK(key_type_ != KeyType::kKeyTypeSecret); if (config.output_key_object) { @@ -294,7 +300,7 @@ Maybe KeyObjectData::ToEncodedPublicKey( return NothingIfFalse( KeyObjectHandle::Create(env, addRefWithType(KeyType::kKeyTypePublic)) .ToLocal(out)); - } else if (config.format == ncrypto::EVPKeyPointer::PKFormatType::JWK) { + } else if (config.format == EVPKeyPointer::PKFormatType::JWK) { *out = Object::New(env->isolate()); return ExportJWKInner( env, addRefWithType(KeyType::kKeyTypePublic), *out, false); @@ -306,14 +312,14 @@ Maybe KeyObjectData::ToEncodedPublicKey( Maybe KeyObjectData::ToEncodedPrivateKey( Environment* env, - const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config, + const EVPKeyPointer::PrivateKeyEncodingConfig& config, Local* out) { CHECK(key_type_ != KeyType::kKeyTypeSecret); if (config.output_key_object) { return NothingIfFalse( KeyObjectHandle::Create(env, addRefWithType(KeyType::kKeyTypePrivate)) .ToLocal(out)); - } else if (config.format == ncrypto::EVPKeyPointer::PKFormatType::JWK) { + } else if (config.format == EVPKeyPointer::PKFormatType::JWK) { *out = Object::New(env->isolate()); return ExportJWKInner( env, addRefWithType(KeyType::kKeyTypePrivate), *out, false); @@ -323,16 +329,16 @@ Maybe KeyObjectData::ToEncodedPrivateKey( WritePrivateKey(env, GetAsymmetricKey(), config).ToLocal(out)); } -Maybe +Maybe KeyObjectData::GetPrivateKeyEncodingFromJs( const FunctionCallbackInfo& args, unsigned int* offset, KeyEncodingContext context) { Environment* env = Environment::GetCurrent(args); - ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig config; + EVPKeyPointer::PrivateKeyEncodingConfig config; if (!GetKeyFormatAndTypeFromJs(args, offset, context).To(&config)) { - return Nothing(); + return Nothing(); } if (config.output_key_object) { @@ -346,7 +352,7 @@ KeyObjectData::GetPrivateKeyEncodingFromJs( config.cipher = EVP_get_cipherbyname(*cipher_name); if (config.cipher == nullptr) { THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env); - return Nothing(); + return Nothing(); } needs_passphrase = true; } else { @@ -361,7 +367,7 @@ KeyObjectData::GetPrivateKeyEncodingFromJs( ArrayBufferOrViewContents passphrase(args[*offset]); if (!passphrase.CheckSizeInt32()) [[unlikely]] { THROW_ERR_OUT_OF_RANGE(env, "passphrase is too big"); - return Nothing(); + return Nothing(); } config.passphrase = passphrase.ToDataPointer(); } else { @@ -370,11 +376,10 @@ KeyObjectData::GetPrivateKeyEncodingFromJs( } (*offset)++; - return Just( - std::move(config)); + return Just(std::move(config)); } -Maybe +Maybe KeyObjectData::GetPublicKeyEncodingFromJs( const FunctionCallbackInfo& args, unsigned int* offset, @@ -390,7 +395,7 @@ KeyObjectData KeyObjectData::GetPrivateKeyFromJs( Environment* env = Environment::GetCurrent(args); auto key = ByteSource::FromStringOrBuffer(env, args[(*offset)++]); - ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig config; + EVPKeyPointer::PrivateKeyEncodingConfig config; if (!GetPrivateKeyEncodingFromJs(args, offset, kKeyContextInput) .To(&config)) { return {}; @@ -423,7 +428,7 @@ KeyObjectData KeyObjectData::GetPublicOrPrivateKeyFromJs( return {}; } - ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig config; + EVPKeyPointer::PrivateKeyEncodingConfig config; if (!KeyObjectData::GetPrivateKeyEncodingFromJs( args, offset, kKeyContextInput) .To(&config)) { @@ -435,7 +440,7 @@ KeyObjectData KeyObjectData::GetPublicOrPrivateKeyFromJs( .len = data.size(), }; - if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { + if (config.format == EVPKeyPointer::PKFormatType::PEM) { // For PEM, we can easily determine whether it is a public or private key // by looking for the respective PEM tags. auto res = EVPKeyPointer::TryParsePublicKeyPEM(buffer); @@ -456,13 +461,13 @@ KeyObjectData KeyObjectData::GetPublicOrPrivateKeyFromJs( static const auto is_public = [](const auto& config, const auto& buffer) -> bool { switch (config.type) { - case ncrypto::EVPKeyPointer::PKEncodingType::PKCS1: + case EVPKeyPointer::PKEncodingType::PKCS1: return !EVPKeyPointer::IsRSAPrivateKey(buffer); - case ncrypto::EVPKeyPointer::PKEncodingType::SPKI: + case EVPKeyPointer::PKEncodingType::SPKI: return true; - case ncrypto::EVPKeyPointer::PKEncodingType::PKCS8: + case EVPKeyPointer::PKEncodingType::PKCS8: return false; - case ncrypto::EVPKeyPointer::PKEncodingType::SEC1: + case EVPKeyPointer::PKEncodingType::SEC1: return false; default: UNREACHABLE("Invalid key encoding type"); @@ -755,22 +760,21 @@ void KeyObjectHandle::InitECRaw(const FunctionCallbackInfo& args) { MarkPopErrorOnReturn mark_pop_error_on_return; int id = OBJ_txt2nid(*name); - ECKeyPointer eckey(EC_KEY_new_by_curve_name(id)); + auto eckey = ECKeyPointer::NewByCurveName(id); if (!eckey) return args.GetReturnValue().Set(false); - const EC_GROUP* group = EC_KEY_get0_group(eckey.get()); - ECPointPointer pub(ECDH::BufferToPoint(env, group, args[1])); + const auto group = eckey.getGroup(); + auto pub = ECDH::BufferToPoint(env, group, args[1]); - if (!pub || - !eckey || - !EC_KEY_set_public_key(eckey.get(), pub.get())) { + if (!pub || !eckey || !eckey.setPublicKey(pub)) { return args.GetReturnValue().Set(false); } auto pkey = EVPKeyPointer::New(); - if (!EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get())) + if (!pkey.assign(eckey)) { args.GetReturnValue().Set(false); + } eckey.release(); // Release ownership of the key @@ -990,7 +994,7 @@ void KeyObjectHandle::Export(const FunctionCallbackInfo& args) { result = key->ExportSecretKey(); } else if (type == kKeyTypePublic) { unsigned int offset = 0; - ncrypto::EVPKeyPointer::PublicKeyEncodingConfig config; + EVPKeyPointer::PublicKeyEncodingConfig config; if (!KeyObjectData::GetPublicKeyEncodingFromJs( args, &offset, kKeyContextExport) .To(&config)) { @@ -1001,7 +1005,7 @@ void KeyObjectHandle::Export(const FunctionCallbackInfo& args) { } else { CHECK_EQ(type, kKeyTypePrivate); unsigned int offset = 0; - ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig config; + EVPKeyPointer::PrivateKeyEncodingConfig config; if (!KeyObjectData::GetPrivateKeyEncodingFromJs( args, &offset, kKeyContextExport) .To(&config)) { @@ -1022,12 +1026,12 @@ MaybeLocal KeyObjectHandle::ExportSecretKey() const { } MaybeLocal KeyObjectHandle::ExportPublicKey( - const ncrypto::EVPKeyPointer::PublicKeyEncodingConfig& config) const { + const EVPKeyPointer::PublicKeyEncodingConfig& config) const { return WritePublicKey(env(), data_.GetAsymmetricKey(), config); } MaybeLocal KeyObjectHandle::ExportPrivateKey( - const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config) const { + const EVPKeyPointer::PrivateKeyEncodingConfig& config) const { return WritePrivateKey(env(), data_.GetAsymmetricKey(), config); } @@ -1184,19 +1188,19 @@ void Initialize(Environment* env, Local target) { KeyObjectHandle::Initialize(env)).Check(); constexpr int kKeyEncodingPKCS1 = - static_cast(ncrypto::EVPKeyPointer::PKEncodingType::PKCS1); + static_cast(EVPKeyPointer::PKEncodingType::PKCS1); constexpr int kKeyEncodingPKCS8 = - static_cast(ncrypto::EVPKeyPointer::PKEncodingType::PKCS8); + static_cast(EVPKeyPointer::PKEncodingType::PKCS8); constexpr int kKeyEncodingSPKI = - static_cast(ncrypto::EVPKeyPointer::PKEncodingType::SPKI); + static_cast(EVPKeyPointer::PKEncodingType::SPKI); constexpr int kKeyEncodingSEC1 = - static_cast(ncrypto::EVPKeyPointer::PKEncodingType::SEC1); + static_cast(EVPKeyPointer::PKEncodingType::SEC1); constexpr int kKeyFormatDER = - static_cast(ncrypto::EVPKeyPointer::PKFormatType::DER); + static_cast(EVPKeyPointer::PKFormatType::DER); constexpr int kKeyFormatPEM = - static_cast(ncrypto::EVPKeyPointer::PKFormatType::PEM); + static_cast(EVPKeyPointer::PKFormatType::PEM); constexpr int kKeyFormatJWK = - static_cast(ncrypto::EVPKeyPointer::PKFormatType::JWK); + static_cast(EVPKeyPointer::PKFormatType::JWK); NODE_DEFINE_CONSTANT(target, kWebCryptoKeyFormatRaw); NODE_DEFINE_CONSTANT(target, kWebCryptoKeyFormatPKCS8); diff --git a/src/crypto/crypto_keys.h b/src/crypto/crypto_keys.h index 32832e87798372..e4f3e03e59bf48 100644 --- a/src/crypto/crypto_keys.h +++ b/src/crypto/crypto_keys.h @@ -33,10 +33,11 @@ enum KeyEncodingContext { enum class ParseKeyResult { kParseKeyNotRecognized = - static_cast(EVPKeyPointer::PKParseError::NOT_RECOGNIZED), + static_cast(ncrypto::EVPKeyPointer::PKParseError::NOT_RECOGNIZED), kParseKeyNeedPassphrase = - static_cast(EVPKeyPointer::PKParseError::NEED_PASSPHRASE), - kParseKeyFailed = static_cast(EVPKeyPointer::PKParseError::FAILED), + static_cast(ncrypto::EVPKeyPointer::PKParseError::NEED_PASSPHRASE), + kParseKeyFailed = + static_cast(ncrypto::EVPKeyPointer::PKParseError::FAILED), kParseKeyOk, }; @@ -45,7 +46,8 @@ class KeyObjectData final : public MemoryRetainer { public: static KeyObjectData CreateSecret(ByteSource key); - static KeyObjectData CreateAsymmetric(KeyType type, EVPKeyPointer&& pkey); + static KeyObjectData CreateAsymmetric(KeyType type, + ncrypto::EVPKeyPointer&& pkey); KeyObjectData(std::nullptr_t = nullptr); @@ -55,7 +57,7 @@ class KeyObjectData final : public MemoryRetainer { // These functions allow unprotected access to the raw key material and should // only be used to implement cryptographic operations requiring the key. - const EVPKeyPointer& GetAsymmetricKey() const; + const ncrypto::EVPKeyPointer& GetAsymmetricKey() const; const char* GetSymmetricKey() const; size_t GetSymmetricKeySize() const; @@ -103,11 +105,11 @@ class KeyObjectData final : public MemoryRetainer { private: explicit KeyObjectData(ByteSource symmetric_key); - explicit KeyObjectData(KeyType type, EVPKeyPointer&& pkey); + explicit KeyObjectData(KeyType type, ncrypto::EVPKeyPointer&& pkey); static KeyObjectData GetParsedKey(KeyType type, Environment* env, - EVPKeyPointer&& pkey, + ncrypto::EVPKeyPointer&& pkey, ParseKeyResult ret, const char* default_msg); @@ -116,10 +118,10 @@ class KeyObjectData final : public MemoryRetainer { struct Data { const ByteSource symmetric_key; - const EVPKeyPointer asymmetric_key; + const ncrypto::EVPKeyPointer asymmetric_key; explicit Data(ByteSource symmetric_key) : symmetric_key(std::move(symmetric_key)) {} - explicit Data(EVPKeyPointer asymmetric_key) + explicit Data(ncrypto::EVPKeyPointer asymmetric_key) : asymmetric_key(std::move(asymmetric_key)) {} }; std::shared_ptr data_; diff --git a/src/crypto/crypto_random.cc b/src/crypto/crypto_random.cc index a6a206455b52c3..28dd2d6d0e276c 100644 --- a/src/crypto/crypto_random.cc +++ b/src/crypto/crypto_random.cc @@ -11,6 +11,8 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::ClearErrorOnReturn; using v8::ArrayBuffer; using v8::BackingStore; using v8::Boolean; @@ -27,8 +29,7 @@ using v8::Value; namespace crypto { namespace { -ncrypto::BignumPointer::PrimeCheckCallback getPrimeCheckCallback( - Environment* env) { +BignumPointer::PrimeCheckCallback getPrimeCheckCallback(Environment* env) { // The callback is used to check if the operation should be stopped. // Currently, the only check we perform is if env->is_stopping() // is true. diff --git a/src/crypto/crypto_random.h b/src/crypto/crypto_random.h index 01cfc38f45e2f9..8b3193c24f6aa1 100644 --- a/src/crypto/crypto_random.h +++ b/src/crypto/crypto_random.h @@ -45,9 +45,9 @@ struct RandomBytesTraits final { using RandomBytesJob = DeriveBitsJob; struct RandomPrimeConfig final : public MemoryRetainer { - BignumPointer prime; - BignumPointer rem; - BignumPointer add; + ncrypto::BignumPointer prime; + ncrypto::BignumPointer rem; + ncrypto::BignumPointer add; int bits; bool safe; void MemoryInfo(MemoryTracker* tracker) const override; @@ -80,7 +80,7 @@ struct RandomPrimeTraits final { using RandomPrimeJob = DeriveBitsJob; struct CheckPrimeConfig final : public MemoryRetainer { - BignumPointer candidate; + ncrypto::BignumPointer candidate; int checks = 1; void MemoryInfo(MemoryTracker* tracker) const override; diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index 6d360554b31d53..05a3882c7e17d7 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -14,6 +14,10 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::EVPKeyCtxPointer; +using ncrypto::EVPKeyPointer; +using ncrypto::RSAPointer; using v8::ArrayBuffer; using v8::BackingStore; using v8::FunctionCallbackInfo; diff --git a/src/crypto/crypto_rsa.h b/src/crypto/crypto_rsa.h index cbab0ef15acdf7..29b259ae2f5284 100644 --- a/src/crypto/crypto_rsa.h +++ b/src/crypto/crypto_rsa.h @@ -41,7 +41,7 @@ struct RsaKeyGenTraits final { using AdditionalParameters = RsaKeyPairGenConfig; static constexpr const char* JobName = "RsaKeyPairGenJob"; - static EVPKeyCtxPointer Setup(RsaKeyPairGenConfig* params); + static ncrypto::EVPKeyCtxPointer Setup(RsaKeyPairGenConfig* params); static v8::Maybe AdditionalConfig( CryptoJobMode mode, diff --git a/src/crypto/crypto_sig.cc b/src/crypto/crypto_sig.cc index 0e808013a31f9d..abb8a804c1b508 100644 --- a/src/crypto/crypto_sig.cc +++ b/src/crypto/crypto_sig.cc @@ -12,6 +12,13 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::ClearErrorOnReturn; +using ncrypto::ECDSASigPointer; +using ncrypto::ECKeyPointer; +using ncrypto::EVPKeyCtxPointer; +using ncrypto::EVPKeyPointer; +using ncrypto::EVPMDCtxPointer; using v8::ArrayBuffer; using v8::BackingStore; using v8::Boolean; @@ -129,9 +136,7 @@ unsigned int GetBytesOfRS(const EVPKeyPointer& pkey) { // Both r and s are computed mod q, so their width is limited by that of q. bits = BignumPointer::GetBitCount(DSA_get0_q(dsa_key)); } else if (base_id == EVP_PKEY_EC) { - const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get()); - const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key); - bits = EC_GROUP_order_bits(ec_group); + bits = EC_GROUP_order_bits(ECKeyPointer::GetGroup(pkey)); } else { return kNoDsaSignature; } @@ -144,16 +149,16 @@ bool ExtractP1363( unsigned char* out, size_t len, size_t n) { - ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, len)); + ncrypto::Buffer sig_buffer{ + .data = sig_data, + .len = len, + }; + auto asn1_sig = ECDSASigPointer::Parse(sig_buffer); if (!asn1_sig) return false; - const BIGNUM* pr; - const BIGNUM* ps; - ECDSA_SIG_get0(asn1_sig.get(), &pr, &ps); - - return BignumPointer::EncodePaddedInto(pr, out, n) > 0 && - BignumPointer::EncodePaddedInto(ps, out + n, n) > 0; + return BignumPointer::EncodePaddedInto(asn1_sig.r(), out, n) > 0 && + BignumPointer::EncodePaddedInto(asn1_sig.s(), out + n, n) > 0; } // Returns the maximum size of each of the integers (r, s) of the DSA signature. @@ -207,23 +212,19 @@ ByteSource ConvertSignatureToDER(const EVPKeyPointer& pkey, ByteSource&& out) { if (out.size() != 2 * n) return ByteSource(); - ECDSASigPointer asn1_sig(ECDSA_SIG_new()); + auto asn1_sig = ECDSASigPointer::New(); CHECK(asn1_sig); BignumPointer r(sig_data, n); CHECK(r); BignumPointer s(sig_data + n, n); CHECK(s); - CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r.release(), s.release())); - - unsigned char* data = nullptr; - int len = i2d_ECDSA_SIG(asn1_sig.get(), &data); - - if (len <= 0) - return ByteSource(); + CHECK(asn1_sig.setParams(std::move(r), std::move(s))); - CHECK_NOT_NULL(data); + auto buf = asn1_sig.encode(); + if (buf.len <= 0) return ByteSource(); - return ByteSource::Allocated(data, len); + CHECK_NOT_NULL(buf.data); + return ByteSource::Allocated(buf); } void CheckThrow(Environment* env, SignBase::Error error) { diff --git a/src/crypto/crypto_sig.h b/src/crypto/crypto_sig.h index 14c553fe3fca66..3a3c27b4e8e748 100644 --- a/src/crypto/crypto_sig.h +++ b/src/crypto/crypto_sig.h @@ -42,7 +42,7 @@ class SignBase : public BaseObject { SET_SELF_SIZE(SignBase) protected: - EVPMDCtxPointer mdctx_; + ncrypto::EVPMDCtxPointer mdctx_; }; class Sign : public SignBase { @@ -60,7 +60,7 @@ class Sign : public SignBase { : error(err), signature(std::move(sig)) {} }; - SignResult SignFinal(const EVPKeyPointer& pkey, + SignResult SignFinal(const ncrypto::EVPKeyPointer& pkey, int padding, const v8::Maybe& saltlen, DSASigEnc dsa_sig_enc); @@ -81,7 +81,7 @@ class Verify : public SignBase { static void Initialize(Environment* env, v8::Local target); static void RegisterExternalReferences(ExternalReferenceRegistry* registry); - Error VerifyFinal(const EVPKeyPointer& key, + Error VerifyFinal(const ncrypto::EVPKeyPointer& key, const ByteSource& sig, int padding, const v8::Maybe& saltlen, diff --git a/src/crypto/crypto_spkac.cc b/src/crypto/crypto_spkac.cc index d0dcb1d7be5581..ba085226984767 100644 --- a/src/crypto/crypto_spkac.cc +++ b/src/crypto/crypto_spkac.cc @@ -9,6 +9,7 @@ namespace node { +using ncrypto::BIOPointer; using v8::Context; using v8::FunctionCallbackInfo; using v8::Local; diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index 21a4e7538366be..0f1defef16661a 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -36,6 +36,12 @@ namespace node { +using ncrypto::BIOPointer; +using ncrypto::ClearErrorOnReturn; +using ncrypto::MarkPopErrorOnReturn; +using ncrypto::SSLPointer; +using ncrypto::SSLSessionPointer; +using ncrypto::X509Pointer; using v8::Array; using v8::ArrayBuffer; using v8::ArrayBufferView; diff --git a/src/crypto/crypto_tls.h b/src/crypto/crypto_tls.h index 1faad67a4a2886..ed1ee337b42ec1 100644 --- a/src/crypto/crypto_tls.h +++ b/src/crypto/crypto_tls.h @@ -248,8 +248,8 @@ class TLSWrap : public AsyncWrap, Environment* const env_; Kind kind_; - SSLSessionPointer next_sess_; - SSLPointer ssl_; + ncrypto::SSLSessionPointer next_sess_; + ncrypto::SSLPointer ssl_; ClientHelloParser hello_parser_; v8::Global ocsp_response_; BaseObjectPtr sni_context_; @@ -288,7 +288,7 @@ class TLSWrap : public AsyncWrap, CertCb cert_cb_ = nullptr; void* cert_cb_arg_ = nullptr; - BIOPointer bio_trace_; + ncrypto::BIOPointer bio_trace_; bool has_active_write_issued_by_prev_listener_ = false; diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc index 9f5f8e6f03e4ab..2470d3c89577f1 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -26,6 +26,11 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::BIOPointer; +using ncrypto::CryptoErrorList; +using ncrypto::EnginePointer; +using ncrypto::EVPKeyCtxPointer; using v8::ArrayBuffer; using v8::BackingStore; using v8::BigInt; @@ -162,7 +167,7 @@ void InitCryptoOnce() { sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); #ifndef OPENSSL_NO_ENGINE - ncrypto::EnginePointer::initEnginesOnce(); + EnginePointer::initEnginesOnce(); #endif // !OPENSSL_NO_ENGINE } @@ -181,7 +186,7 @@ void SetFipsCrypto(const FunctionCallbackInfo& args) { CHECK(env->owns_process_state()); bool enable = args[0]->BooleanValue(env->isolate()); - ncrypto::CryptoErrorList errors; + CryptoErrorList errors; if (!ncrypto::setFipsEnabled(enable, &errors)) { Local exception; if (cryptoErrorListToException(env, errors).ToLocal(&exception)) { @@ -210,8 +215,8 @@ bool CryptoErrorStore::Empty() const { return errors_.empty(); } -MaybeLocal cryptoErrorListToException( - Environment* env, const ncrypto::CryptoErrorList& errors) { +MaybeLocal cryptoErrorListToException(Environment* env, + const CryptoErrorList& errors) { // The CryptoErrorList contains a listing of zero or more errors. // If there are no errors, it is likely a bug but we will return // an error anyway. @@ -587,7 +592,7 @@ void SetEngine(const FunctionCallbackInfo& args) { // If the engine name is not known, calling setAsDefault on the // empty engine pointer will be non-op that always returns false. args.GetReturnValue().Set( - ncrypto::EnginePointer::getEngineByName(engine_id.ToStringView()) + EnginePointer::getEngineByName(engine_id.ToStringView()) .setAsDefault(flags)); } #endif // !OPENSSL_NO_ENGINE @@ -597,7 +602,7 @@ MaybeLocal EncodeBignum( const BIGNUM* bn, int size, Local* error) { - auto buf = ncrypto::BignumPointer::EncodePadded(bn, size); + auto buf = BignumPointer::EncodePadded(bn, size); CHECK_EQ(buf.size(), static_cast(size)); return StringBytes::Encode(env->isolate(), reinterpret_cast(buf.get()), diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index bd38be97094f1e..a5967c7d24b836 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -38,6 +38,7 @@ #include namespace node { + namespace crypto { // Currently known sizes of commonly used OpenSSL struct sizes. // OpenSSL considers it's various structs to be opaque and the @@ -53,33 +54,6 @@ constexpr size_t kSizeOf_EVP_PKEY = 72; constexpr size_t kSizeOf_EVP_PKEY_CTX = 80; constexpr size_t kSizeOf_HMAC_CTX = 32; -// Define smart pointers for the most commonly used OpenSSL types: -using X509Pointer = ncrypto::X509Pointer; -using BIOPointer = ncrypto::BIOPointer; -using SSLCtxPointer = ncrypto::SSLCtxPointer; -using SSLSessionPointer = ncrypto::SSLSessionPointer; -using SSLPointer = ncrypto::SSLPointer; -using PKCS8Pointer = ncrypto::PKCS8Pointer; -using EVPKeyPointer = ncrypto::EVPKeyPointer; -using EVPKeyCtxPointer = ncrypto::EVPKeyCtxPointer; -using EVPMDCtxPointer = ncrypto::EVPMDCtxPointer; -using RSAPointer = ncrypto::RSAPointer; -using ECPointer = ncrypto::ECPointer; -using BignumPointer = ncrypto::BignumPointer; -using NetscapeSPKIPointer = ncrypto::NetscapeSPKIPointer; -using ECGroupPointer = ncrypto::ECGroupPointer; -using ECPointPointer = ncrypto::ECPointPointer; -using ECKeyPointer = ncrypto::ECKeyPointer; -using DHPointer = ncrypto::DHPointer; -using ECDSASigPointer = ncrypto::ECDSASigPointer; -using HMACCtxPointer = ncrypto::HMACCtxPointer; -using CipherCtxPointer = ncrypto::CipherCtxPointer; -using DsaPointer = ncrypto::DSAPointer; -using DsaSigPointer = ncrypto::DSASigPointer; - -using ClearErrorOnReturn = ncrypto::ClearErrorOnReturn; -using MarkPopErrorOnReturn = ncrypto::MarkPopErrorOnReturn; - bool ProcessFipsOptions(); bool InitCryptoOnce(v8::Isolate* isolate); @@ -260,8 +234,8 @@ class ByteSource { operator bool() const { return data_ != nullptr; } - BignumPointer ToBN() const { - return BignumPointer(data(), size()); + ncrypto::BignumPointer ToBN() const { + return ncrypto::BignumPointer(data(), size()); } // Creates a v8::BackingStore that takes over responsibility for @@ -296,7 +270,7 @@ class ByteSource { static ByteSource FromBuffer(v8::Local buffer, bool ntc = false); - static ByteSource FromBIO(const BIOPointer& bio); + static ByteSource FromBIO(const ncrypto::BIOPointer& bio); static ByteSource NullTerminatedCopy(Environment* env, v8::Local value); @@ -733,7 +707,8 @@ v8::Maybe SetEncodedValue(Environment* env, const BIGNUM* bn, int size = 0); -bool SetRsaOaepLabel(const EVPKeyCtxPointer& rsa, const ByteSource& label); +bool SetRsaOaepLabel(const ncrypto::EVPKeyCtxPointer& rsa, + const ByteSource& label); namespace Util { void Initialize(Environment* env, v8::Local target); diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc index a19b1d07e02609..3465454e4de4a7 100644 --- a/src/crypto/crypto_x509.cc +++ b/src/crypto/crypto_x509.cc @@ -15,6 +15,15 @@ namespace node { +using ncrypto::BignumPointer; +using ncrypto::BIOPointer; +using ncrypto::ClearErrorOnReturn; +using ncrypto::DataPointer; +using ncrypto::ECKeyPointer; +using ncrypto::SSLPointer; +using ncrypto::StackOfASN1; +using ncrypto::X509Pointer; +using ncrypto::X509View; using v8::Array; using v8::ArrayBuffer; using v8::ArrayBufferView; @@ -62,7 +71,7 @@ void ManagedX509::MemoryInfo(MemoryTracker* tracker) const { namespace { MaybeLocal GetFingerprintDigest(Environment* env, const EVP_MD* method, - const ncrypto::X509View& cert) { + const X509View& cert) { auto fingerprint = cert.getFingerprint(method); // Returning an empty string indicates that the digest failed for // some reason. @@ -129,7 +138,7 @@ MaybeLocal ToV8Value(Local context, const ASN1_STRING* str) { if (value_str_size < 0) { return Undefined(context->GetIsolate()); } - ncrypto::DataPointer free_value_str(value_str, value_str_size); + DataPointer free_value_str(value_str, value_str_size); Local result; if (!String::NewFromUtf8(context->GetIsolate(), @@ -171,7 +180,7 @@ MaybeLocal ToBuffer(Environment* env, BIOPointer* bio) { return ret; } -MaybeLocal GetDer(Environment* env, const ncrypto::X509View& view) { +MaybeLocal GetDer(Environment* env, const X509View& view) { Local ret; auto bio = view.toDER(); if (!bio) return Undefined(env->isolate()); @@ -182,7 +191,7 @@ MaybeLocal GetDer(Environment* env, const ncrypto::X509View& view) { } MaybeLocal GetSubjectAltNameString(Environment* env, - const ncrypto::X509View& view) { + const X509View& view) { Local ret; auto bio = view.getSubjectAltName(); if (!bio) return Undefined(env->isolate()); @@ -190,8 +199,7 @@ MaybeLocal GetSubjectAltNameString(Environment* env, return ret; } -MaybeLocal GetInfoAccessString(Environment* env, - const ncrypto::X509View& view) { +MaybeLocal GetInfoAccessString(Environment* env, const X509View& view) { Local ret; auto bio = view.getInfoAccess(); if (!bio) return Undefined(env->isolate()); @@ -201,8 +209,7 @@ MaybeLocal GetInfoAccessString(Environment* env, return ret; } -MaybeLocal GetValidFrom(Environment* env, - const ncrypto::X509View& view) { +MaybeLocal GetValidFrom(Environment* env, const X509View& view) { Local ret; auto bio = view.getValidFrom(); if (!bio) return Undefined(env->isolate()); @@ -212,7 +219,7 @@ MaybeLocal GetValidFrom(Environment* env, return ret; } -MaybeLocal GetValidTo(Environment* env, const ncrypto::X509View& view) { +MaybeLocal GetValidTo(Environment* env, const X509View& view) { Local ret; auto bio = view.getValidTo(); if (!bio) return Undefined(env->isolate()); @@ -222,20 +229,17 @@ MaybeLocal GetValidTo(Environment* env, const ncrypto::X509View& view) { return ret; } -MaybeLocal GetValidFromDate(Environment* env, - const ncrypto::X509View& view) { +MaybeLocal GetValidFromDate(Environment* env, const X509View& view) { int64_t validFromTime = view.getValidFromTime(); return Date::New(env->context(), validFromTime * 1000.); } -MaybeLocal GetValidToDate(Environment* env, - const ncrypto::X509View& view) { +MaybeLocal GetValidToDate(Environment* env, const X509View& view) { int64_t validToTime = view.getValidToTime(); return Date::New(env->context(), validToTime * 1000.); } -MaybeLocal GetSerialNumber(Environment* env, - const ncrypto::X509View& view) { +MaybeLocal GetSerialNumber(Environment* env, const X509View& view) { if (auto serial = view.getSerialNumber()) { return OneByteString(env->isolate(), static_cast(serial.get())); @@ -243,8 +247,8 @@ MaybeLocal GetSerialNumber(Environment* env, return Undefined(env->isolate()); } -MaybeLocal GetKeyUsage(Environment* env, const ncrypto::X509View& cert) { - ncrypto::StackOfASN1 eku(static_cast( +MaybeLocal GetKeyUsage(Environment* env, const X509View& cert) { + StackOfASN1 eku(static_cast( X509_get_ext_d2i(cert.get(), NID_ext_key_usage, nullptr, nullptr))); if (eku) { const int count = sk_ASN1_OBJECT_num(eku.get()); @@ -458,10 +462,10 @@ void CheckHost(const FunctionCallbackInfo& args) { Utf8Value name(env->isolate(), args[0]); uint32_t flags = args[1].As()->Value(); - ncrypto::DataPointer peername; + DataPointer peername; switch (cert->view().checkHost(name.ToStringView(), flags, &peername)) { - case ncrypto::X509View::CheckMatch::MATCH: { // Match! + case X509View::CheckMatch::MATCH: { // Match! Local ret = args[0]; if (peername) { ret = OneByteString(env->isolate(), @@ -470,9 +474,9 @@ void CheckHost(const FunctionCallbackInfo& args) { } return args.GetReturnValue().Set(ret); } - case ncrypto::X509View::CheckMatch::NO_MATCH: // No Match! + case X509View::CheckMatch::NO_MATCH: // No Match! return; // No return value is set - case ncrypto::X509View::CheckMatch::INVALID_NAME: // Error! + case X509View::CheckMatch::INVALID_NAME: // Error! return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name"); default: // Error! return THROW_ERR_CRYPTO_OPERATION_FAILED(env); @@ -491,11 +495,11 @@ void CheckEmail(const FunctionCallbackInfo& args) { uint32_t flags = args[1].As()->Value(); switch (cert->view().checkEmail(name.ToStringView(), flags)) { - case ncrypto::X509View::CheckMatch::MATCH: // Match! + case X509View::CheckMatch::MATCH: // Match! return args.GetReturnValue().Set(args[0]); - case ncrypto::X509View::CheckMatch::NO_MATCH: // No Match! + case X509View::CheckMatch::NO_MATCH: // No Match! return; // No return value is set - case ncrypto::X509View::CheckMatch::INVALID_NAME: // Error! + case X509View::CheckMatch::INVALID_NAME: // Error! return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name"); default: // Error! return THROW_ERR_CRYPTO_OPERATION_FAILED(env); @@ -514,11 +518,11 @@ void CheckIP(const FunctionCallbackInfo& args) { uint32_t flags = args[1].As()->Value(); switch (cert->view().checkIp(name.ToStringView(), flags)) { - case ncrypto::X509View::CheckMatch::MATCH: // Match! + case X509View::CheckMatch::MATCH: // Match! return args.GetReturnValue().Set(args[0]); - case ncrypto::X509View::CheckMatch::NO_MATCH: // No Match! + case X509View::CheckMatch::NO_MATCH: // No Match! return; // No return value is set - case ncrypto::X509View::CheckMatch::INVALID_NAME: // Error! + case X509View::CheckMatch::INVALID_NAME: // Error! return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP"); default: // Error! return THROW_ERR_CRYPTO_OPERATION_FAILED(env); @@ -594,7 +598,7 @@ bool Set(Environment* env, // The property value may be a single string or an array of strings. template static MaybeLocal GetX509NameObject(Environment* env, - const ncrypto::X509View& cert) { + const X509View& cert) { X509_NAME* name = get_name(cert.get()); CHECK_NOT_NULL(name); @@ -694,7 +698,7 @@ MaybeLocal GetExponentString(Environment* env, const BIGNUM* e) { MaybeLocal GetECPubKey(Environment* env, const EC_GROUP* group, OSSL3_CONST EC_KEY* ec) { - const EC_POINT* pubkey = EC_KEY_get0_public_key(ec); + const auto pubkey = ECKeyPointer::GetPublicKey(ec); if (pubkey == nullptr) return Undefined(env->isolate()); return ECPointToBuffer(env, group, pubkey, EC_KEY_get_conv_form(ec), nullptr) @@ -718,8 +722,7 @@ MaybeLocal GetCurveName(Environment* env, const int nid) { : MaybeLocal(Undefined(env->isolate())); } -MaybeLocal X509ToObject(Environment* env, - const ncrypto::X509View& cert) { +MaybeLocal X509ToObject(Environment* env, const X509View& cert) { EscapableHandleScope scope(env->isolate()); Local info = Object::New(env->isolate()); @@ -777,7 +780,7 @@ MaybeLocal X509ToObject(Environment* env, return {}; } } else if (ec) { - const EC_GROUP* group = EC_KEY_get0_group(ec); + const auto group = ECKeyPointer::GetGroup(ec); if (!Set( env, info, env->bits_string(), GetECGroupBits(env, group)) || @@ -906,7 +909,7 @@ MaybeLocal X509Certificate::New(Environment* env, MaybeLocal X509Certificate::GetCert(Environment* env, const SSLPointer& ssl) { - auto cert = ncrypto::X509View::From(ssl); + auto cert = X509View::From(ssl); if (!cert) return {}; return New(env, cert.clone()); } @@ -940,8 +943,8 @@ v8::MaybeLocal X509Certificate::toObject(Environment* env) { return toObject(env, view()); } -v8::MaybeLocal X509Certificate::toObject( - Environment* env, const ncrypto::X509View& cert) { +v8::MaybeLocal X509Certificate::toObject(Environment* env, + const X509View& cert) { if (!cert) return {}; return X509ToObject(env, cert).FromMaybe(Local()); } diff --git a/src/crypto/crypto_x509.h b/src/crypto/crypto_x509.h index 595a2344641030..54f4b2a40732d2 100644 --- a/src/crypto/crypto_x509.h +++ b/src/crypto/crypto_x509.h @@ -21,7 +21,7 @@ namespace crypto { class ManagedX509 final : public MemoryRetainer { public: ManagedX509() = default; - explicit ManagedX509(X509Pointer&& cert); + explicit ManagedX509(ncrypto::X509Pointer&& cert); ManagedX509(const ManagedX509& that); ManagedX509& operator=(const ManagedX509& that); @@ -35,7 +35,7 @@ class ManagedX509 final : public MemoryRetainer { SET_SELF_SIZE(ManagedX509) private: - X509Pointer cert_; + ncrypto::X509Pointer cert_; }; class X509Certificate final : public BaseObject { @@ -53,27 +53,24 @@ class X509Certificate final : public BaseObject { static v8::MaybeLocal New( Environment* env, - X509Pointer cert, - STACK_OF(X509)* issuer_chain = nullptr); + ncrypto::X509Pointer cert, + STACK_OF(X509) * issuer_chain = nullptr); static v8::MaybeLocal New( Environment* env, std::shared_ptr cert, STACK_OF(X509)* issuer_chain = nullptr); - static v8::MaybeLocal GetCert( - Environment* env, - const SSLPointer& ssl); + static v8::MaybeLocal GetCert(Environment* env, + const ncrypto::SSLPointer& ssl); - static v8::MaybeLocal GetPeerCert( - Environment* env, - const SSLPointer& ssl, - GetPeerCertificateFlag flag); + static v8::MaybeLocal GetPeerCert(Environment* env, + const ncrypto::SSLPointer& ssl, + GetPeerCertificateFlag flag); - static v8::Local Wrap( - Environment* env, - v8::Local object, - X509Pointer cert); + static v8::Local Wrap(Environment* env, + v8::Local object, + ncrypto::X509Pointer cert); inline BaseObjectPtr getIssuerCert() const { return issuer_cert_; diff --git a/src/quic/tlscontext.cc b/src/quic/tlscontext.cc index 8e2995589c9116..c8f88b34561eb2 100644 --- a/src/quic/tlscontext.cc +++ b/src/quic/tlscontext.cc @@ -20,6 +20,13 @@ namespace node { +using ncrypto::BIOPointer; +using ncrypto::ClearErrorOnReturn; +using ncrypto::MarkPopErrorOnReturn; +using ncrypto::SSLCtxPointer; +using ncrypto::SSLPointer; +using ncrypto::SSLSessionPointer; +using ncrypto::X509Pointer; using v8::ArrayBuffer; using v8::Just; using v8::Local; @@ -43,7 +50,7 @@ namespace { // return 0; // }(); -void EnableTrace(Environment* env, crypto::BIOPointer* bio, SSL* ssl) { +void EnableTrace(Environment* env, BIOPointer* bio, SSL* ssl) { #if HAVE_SSL_TRACE static bool warn_trace_tls = true; if (warn_trace_tls) { @@ -63,7 +70,7 @@ void EnableTrace(Environment* env, crypto::BIOPointer* bio, SSL* ssl) { size_t len, SSL* ssl, void* arg) -> void { - crypto::MarkPopErrorOnReturn mark_pop_error_on_return; + MarkPopErrorOnReturn mark_pop_error_on_return; SSL_trace(write_p, version, content_type, buf, len, ssl, arg); }); SSL_set_msg_callback_arg(ssl, bio->get()); @@ -240,12 +247,12 @@ std::unique_ptr TLSContext::NewSession( session, shared_from_this(), maybeSessionTicket); } -crypto::SSLCtxPointer TLSContext::Initialize() { - crypto::SSLCtxPointer ctx; +SSLCtxPointer TLSContext::Initialize() { + SSLCtxPointer ctx; switch (side_) { case Side::SERVER: { static constexpr unsigned char kSidCtx[] = "Node.js QUIC Server"; - ctx = crypto::SSLCtxPointer::NewServer(); + ctx = SSLCtxPointer::NewServer(); CHECK_EQ(ngtcp2_crypto_quictls_configure_server_context(ctx.get()), 0); CHECK_EQ(SSL_CTX_set_max_early_data(ctx.get(), UINT32_MAX), 1); SSL_CTX_set_options(ctx.get(), @@ -276,7 +283,7 @@ crypto::SSLCtxPointer TLSContext::Initialize() { break; } case Side::CLIENT: { - ctx = crypto::SSLCtxPointer::NewClient(); + ctx = SSLCtxPointer::NewClient(); CHECK_EQ(ngtcp2_crypto_quictls_configure_client_context(ctx.get()), 0); SSL_CTX_set_session_cache_mode( @@ -291,16 +298,16 @@ crypto::SSLCtxPointer TLSContext::Initialize() { if (SSL_CTX_set_ciphersuites(ctx.get(), options_.ciphers.c_str()) != 1) { validation_error_ = "Invalid cipher suite"; - return crypto::SSLCtxPointer(); + return SSLCtxPointer(); } if (SSL_CTX_set1_groups_list(ctx.get(), options_.groups.c_str()) != 1) { validation_error_ = "Invalid cipher groups"; - return crypto::SSLCtxPointer(); + return SSLCtxPointer(); } { - crypto::ClearErrorOnReturn clear_error_on_return; + ClearErrorOnReturn clear_error_on_return; if (options_.ca.empty()) { auto store = crypto::GetOrCreateRootCertStore(); X509_STORE_up_ref(store); @@ -313,14 +320,12 @@ crypto::SSLCtxPointer TLSContext::Initialize() { X509_STORE_up_ref(store); SSL_CTX_set_cert_store(ctx.get(), store); } else { - crypto::BIOPointer bio = crypto::NodeBIO::NewFixed(buf.base, buf.len); + BIOPointer bio = crypto::NodeBIO::NewFixed(buf.base, buf.len); CHECK(bio); X509_STORE* cert_store = SSL_CTX_get_cert_store(ctx.get()); - while (crypto::X509Pointer x509 = crypto::X509Pointer( - PEM_read_bio_X509_AUX(bio.get(), - nullptr, - crypto::NoPasswordCallback, - nullptr))) { + while ( + auto x509 = X509Pointer(PEM_read_bio_X509_AUX( + bio.get(), nullptr, crypto::NoPasswordCallback, nullptr))) { if (cert_store == crypto::GetOrCreateRootCertStore()) { cert_store = crypto::NewRootCertStore(); SSL_CTX_set_cert_store(ctx.get(), cert_store); @@ -334,48 +339,48 @@ crypto::SSLCtxPointer TLSContext::Initialize() { } { - crypto::ClearErrorOnReturn clear_error_on_return; + ClearErrorOnReturn clear_error_on_return; for (const auto& cert : options_.certs) { uv_buf_t buf = cert; if (buf.len > 0) { - crypto::BIOPointer bio = crypto::NodeBIO::NewFixed(buf.base, buf.len); + BIOPointer bio = crypto::NodeBIO::NewFixed(buf.base, buf.len); CHECK(bio); cert_.reset(); issuer_.reset(); if (crypto::SSL_CTX_use_certificate_chain( ctx.get(), std::move(bio), &cert_, &issuer_) == 0) { validation_error_ = "Invalid certificate"; - return crypto::SSLCtxPointer(); + return SSLCtxPointer(); } } } } { - crypto::ClearErrorOnReturn clear_error_on_return; + ClearErrorOnReturn clear_error_on_return; for (const auto& key : options_.keys) { if (key.GetKeyType() != crypto::KeyType::kKeyTypePrivate) { validation_error_ = "Invalid key"; - return crypto::SSLCtxPointer(); + return SSLCtxPointer(); } if (!SSL_CTX_use_PrivateKey(ctx.get(), key.GetAsymmetricKey().get())) { validation_error_ = "Invalid key"; - return crypto::SSLCtxPointer(); + return SSLCtxPointer(); } } } { - crypto::ClearErrorOnReturn clear_error_on_return; + ClearErrorOnReturn clear_error_on_return; for (const auto& crl : options_.crl) { uv_buf_t buf = crl; - crypto::BIOPointer bio = crypto::NodeBIO::NewFixed(buf.base, buf.len); + BIOPointer bio = crypto::NodeBIO::NewFixed(buf.base, buf.len); DeleteFnPtr crlptr(PEM_read_bio_X509_CRL( bio.get(), nullptr, crypto::NoPasswordCallback, nullptr)); if (!crlptr) { validation_error_ = "Invalid CRL"; - return crypto::SSLCtxPointer(); + return SSLCtxPointer(); } X509_STORE* cert_store = SSL_CTX_get_cert_store(ctx.get()); @@ -393,11 +398,11 @@ crypto::SSLCtxPointer TLSContext::Initialize() { } { - crypto::ClearErrorOnReturn clear_error_on_return; + ClearErrorOnReturn clear_error_on_return; if (options_.verify_private_key && SSL_CTX_check_private_key(ctx.get()) != 1) { validation_error_ = "Invalid private key"; - return crypto::SSLCtxPointer(); + return SSLCtxPointer(); } } @@ -514,11 +519,11 @@ bool TLSSession::early_data_was_accepted() const { return SSL_get_early_data_status(*this) == SSL_EARLY_DATA_ACCEPTED; } -crypto::SSLPointer TLSSession::Initialize( +SSLPointer TLSSession::Initialize( const std::optional& maybeSessionTicket) { auto& ctx = context(); auto& options = ctx.options(); - crypto::SSLPointer ssl(SSL_new(ctx)); + SSLPointer ssl(SSL_new(ctx)); SSL_set_app_data(ssl.get(), &ref_); ngtcp2_conn_set_tls_native_handle(*session_, ssl.get()); @@ -541,7 +546,7 @@ crypto::SSLPointer TLSSession::Initialize( reinterpret_cast(options.protocol.data()), options.protocol.size()) != 0) { validation_error_ = "Invalid ALPN"; - return crypto::SSLPointer(); + return SSLPointer(); } if (!options.servername.empty()) { @@ -553,7 +558,7 @@ crypto::SSLPointer TLSSession::Initialize( if (maybeSessionTicket.has_value()) { auto sessionTicket = maybeSessionTicket.value(); uv_buf_t buf = sessionTicket.ticket(); - crypto::SSLSessionPointer ticket = crypto::GetTLSSession( + SSLSessionPointer ticket = crypto::GetTLSSession( reinterpret_cast(buf.base), buf.len); // The early data will just be ignored if it's invalid. diff --git a/src/quic/tlscontext.h b/src/quic/tlscontext.h index 77771d1a252a24..97536f3abecc50 100644 --- a/src/quic/tlscontext.h +++ b/src/quic/tlscontext.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "bindingdata.h" #include "data.h" @@ -84,7 +85,7 @@ class TLSSession final : public MemoryRetainer { private: operator SSL*() const; - crypto::SSLPointer Initialize( + ncrypto::SSLPointer Initialize( const std::optional& maybeSessionTicket); static ngtcp2_conn* connection(ngtcp2_crypto_conn_ref* ref); @@ -92,8 +93,8 @@ class TLSSession final : public MemoryRetainer { ngtcp2_crypto_conn_ref ref_; std::shared_ptr context_; Session* session_; - crypto::SSLPointer ssl_; - crypto::BIOPointer bio_trace_; + ncrypto::SSLPointer ssl_; + ncrypto::BIOPointer bio_trace_; std::string validation_error_ = ""; bool in_key_update_ = false; }; @@ -198,7 +199,7 @@ class TLSContext final : public MemoryRetainer, SET_SELF_SIZE(TLSContext) private: - crypto::SSLCtxPointer Initialize(); + ncrypto::SSLCtxPointer Initialize(); operator SSL_CTX*() const; static void OnKeylog(const SSL* ssl, const char* line); @@ -213,9 +214,9 @@ class TLSContext final : public MemoryRetainer, Side side_; Options options_; - crypto::X509Pointer cert_; - crypto::X509Pointer issuer_; - crypto::SSLCtxPointer ctx_; + ncrypto::X509Pointer cert_; + ncrypto::X509Pointer issuer_; + ncrypto::SSLCtxPointer ctx_; std::string validation_error_ = ""; friend class TLSSession; diff --git a/test/cctest/test_node_crypto_env.cc b/test/cctest/test_node_crypto_env.cc index 001867720f5e80..77aab8f4182d4f 100644 --- a/test/cctest/test_node_crypto_env.cc +++ b/test/cctest/test_node_crypto_env.cc @@ -1,3 +1,4 @@ +#include #include "crypto/crypto_bio.h" #include "gtest/gtest.h" #include "node_options.h" @@ -21,7 +22,7 @@ TEST_F(NodeCryptoEnv, LoadBIO) { Env env{handle_scope, argv}; // just put a random string into BIO Local key = String::NewFromUtf8(isolate_, "abcdef").ToLocalChecked(); - node::crypto::BIOPointer bio(node::crypto::LoadBIO(*env, key)); + ncrypto::BIOPointer bio(node::crypto::LoadBIO(*env, key)); #if OPENSSL_VERSION_NUMBER >= 0x30000000L const int ofs = 2; ASSERT_EQ(BIO_seek(bio.get(), ofs), ofs);