From a11f9ea4f0eceb173c981aeaa987451ad3a7ad0a Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 27 Sep 2021 15:24:40 +0800 Subject: [PATCH] src: register external references in crypto bindings PR-URL: https://github.com/nodejs/node/pull/40239 Refs: https://github.com/nodejs/node/pull/38905 Refs: https://github.com/nodejs/node/issues/37476 Reviewed-By: Anna Henningsen Reviewed-By: Minwoo Jung Reviewed-By: James M Snell --- src/crypto/crypto_aes.cc | 4 ++ src/crypto/crypto_aes.h | 1 + src/crypto/crypto_cipher.cc | 32 ++++++++++++++ src/crypto/crypto_cipher.h | 5 +++ src/crypto/crypto_context.cc | 41 ++++++++++++++++++ src/crypto/crypto_context.h | 1 + src/crypto/crypto_dh.cc | 22 ++++++++++ src/crypto/crypto_dh.h | 1 + src/crypto/crypto_dsa.cc | 5 +++ src/crypto/crypto_dsa.h | 1 + src/crypto/crypto_ec.cc | 16 +++++++ src/crypto/crypto_ec.h | 2 + src/crypto/crypto_hash.cc | 9 ++++ src/crypto/crypto_hash.h | 1 + src/crypto/crypto_hmac.cc | 8 ++++ src/crypto/crypto_hmac.h | 1 + src/crypto/crypto_keygen.cc | 6 +++ src/crypto/crypto_keygen.h | 5 +++ src/crypto/crypto_keys.cc | 24 +++++++++++ src/crypto/crypto_keys.h | 7 ++++ src/crypto/crypto_random.cc | 6 +++ src/crypto/crypto_random.h | 1 + src/crypto/crypto_rsa.cc | 6 +++ src/crypto/crypto_rsa.h | 1 + src/crypto/crypto_sig.cc | 15 +++++++ src/crypto/crypto_sig.h | 2 + src/crypto/crypto_spkac.cc | 5 +++ src/crypto/crypto_spkac.h | 1 + src/crypto/crypto_timing.cc | 3 ++ src/crypto/crypto_timing.h | 2 +- src/crypto/crypto_tls.cc | 52 +++++++++++++++++++++++ src/crypto/crypto_tls.h | 1 + src/crypto/crypto_util.cc | 24 +++++++++++ src/crypto/crypto_util.h | 13 ++++++ src/crypto/crypto_x509.cc | 26 ++++++++++++ src/crypto/crypto_x509.h | 1 + src/node_crypto.cc | 78 +++++++++++++++++++++-------------- src/node_external_reference.h | 9 +++- 38 files changed, 405 insertions(+), 33 deletions(-) diff --git a/src/crypto/crypto_aes.cc b/src/crypto/crypto_aes.cc index d6f6393df6c878..e6a6c77cba2771 100644 --- a/src/crypto/crypto_aes.cc +++ b/src/crypto/crypto_aes.cc @@ -603,5 +603,9 @@ void AES::Initialize(Environment* env, Local target) { #undef V } +void AES::RegisterExternalReferences(ExternalReferenceRegistry* registry) { + AESCryptoJob::RegisterExternalReferences(registry); +} + } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_aes.h b/src/crypto/crypto_aes.h index d6eefffb4a846c..3ffe04766cc339 100644 --- a/src/crypto/crypto_aes.h +++ b/src/crypto/crypto_aes.h @@ -81,6 +81,7 @@ using AESCryptoJob = CipherJob; namespace AES { void Initialize(Environment* env, v8::Local target); +void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace AES } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 6abfc2cce7da79..64ac5ca1277a7a 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -297,6 +297,38 @@ void CipherBase::Initialize(Environment* env, Local target) { NODE_DEFINE_CONSTANT(target, kWebCryptoCipherDecrypt); } +void CipherBase::RegisterExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(New); + + registry->Register(Init); + registry->Register(InitIv); + registry->Register(Update); + registry->Register(Final); + registry->Register(SetAutoPadding); + registry->Register(GetAuthTag); + registry->Register(SetAuthTag); + registry->Register(SetAAD); + + registry->Register(GetSSLCiphers); + registry->Register(GetCiphers); + + registry->Register(PublicKeyCipher::Cipher); + registry->Register(PublicKeyCipher::Cipher); + registry->Register(PublicKeyCipher::Cipher); + registry->Register(PublicKeyCipher::Cipher); + + registry->Register(GetCipherInfo); +} + void CipherBase::New(const FunctionCallbackInfo& args) { CHECK(args.IsConstructCall()); Environment* env = Environment::GetCurrent(args); diff --git a/src/crypto/crypto_cipher.h b/src/crypto/crypto_cipher.h index b9b850a1d64c8b..ac6ec3682f4177 100644 --- a/src/crypto/crypto_cipher.h +++ b/src/crypto/crypto_cipher.h @@ -21,6 +21,7 @@ class CipherBase : public BaseObject { static void GetCiphers(const v8::FunctionCallbackInfo& args); static void Initialize(Environment* env, v8::Local target); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(CipherBase) @@ -190,6 +191,10 @@ class CipherJob final : public CryptoJob { CryptoJob::Initialize(New, env, target); } + static void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + CryptoJob::RegisterExternalReferences(New, registry); + } + CipherJob( Environment* env, v8::Local object, diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index 2264f8f8f89d90..4ecd8a8c4204fc 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -339,6 +339,47 @@ void SecureContext::Initialize(Environment* env, Local target) { IsExtraRootCertsFileLoaded); } +void SecureContext::RegisterExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(New); + registry->Register(Init); + registry->Register(SetKey); + registry->Register(SetCert); + registry->Register(AddCACert); + registry->Register(AddCRL); + registry->Register(AddRootCerts); + registry->Register(SetCipherSuites); + registry->Register(SetCiphers); + registry->Register(SetSigalgs); + registry->Register(SetECDHCurve); + registry->Register(SetDHParam); + registry->Register(SetMaxProto); + registry->Register(SetMinProto); + registry->Register(GetMaxProto); + registry->Register(GetMinProto); + registry->Register(SetOptions); + registry->Register(SetSessionIdContext); + registry->Register(SetSessionTimeout); + registry->Register(Close); + registry->Register(LoadPKCS12); + registry->Register(SetTicketKeys); + registry->Register(SetFreeListLength); + registry->Register(EnableTicketKeyCallback); + registry->Register(GetTicketKeys); + registry->Register(GetCertificate); + registry->Register(GetCertificate); + +#ifndef OPENSSL_NO_ENGINE + registry->Register(SetEngineKey); + registry->Register(SetClientCertEngine); +#endif // !OPENSSL_NO_ENGINE + + registry->Register(CtxGetter); + + registry->Register(GetRootCertificates); + registry->Register(IsExtraRootCertsFileLoaded); +} + SecureContext* SecureContext::Create(Environment* env) { Local obj; if (!GetConstructorTemplate(env) diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h index b857019e47e188..d9b33a4736f13a 100644 --- a/src/crypto/crypto_context.h +++ b/src/crypto/crypto_context.h @@ -38,6 +38,7 @@ class SecureContext final : public BaseObject { static v8::Local GetConstructorTemplate( Environment* env); static void Initialize(Environment* env, v8::Local target); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); static SecureContext* Create(Environment* env); SSL_CTX* operator*() const { return ctx_.get(); } diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index 86475e3b1b1e01..7e99759654e8b9 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -108,6 +108,28 @@ void DiffieHellman::Initialize(Environment* env, Local target) { DHBitsJob::Initialize(env, target); } +void DiffieHellman::RegisterExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(New); + registry->Register(DiffieHellmanGroup); + + registry->Register(GenerateKeys); + registry->Register(ComputeSecret); + registry->Register(GetPrime); + registry->Register(GetGenerator); + registry->Register(GetPublicKey); + registry->Register(GetPrivateKey); + registry->Register(SetPublicKey); + registry->Register(SetPrivateKey); + + registry->Register(DiffieHellman::VerifyErrorGetter); + registry->Register(DiffieHellman::Stateless); + + DHKeyPairGenJob::RegisterExternalReferences(registry); + DHKeyExportJob::RegisterExternalReferences(registry); + DHBitsJob::RegisterExternalReferences(registry); +} + bool DiffieHellman::Init(int primeLength, int g) { dh_.reset(DH_new()); if (!DH_generate_parameters_ex(dh_.get(), primeLength, g, nullptr)) diff --git a/src/crypto/crypto_dh.h b/src/crypto/crypto_dh.h index fecbf41070bda4..cb3664fb79c303 100644 --- a/src/crypto/crypto_dh.h +++ b/src/crypto/crypto_dh.h @@ -17,6 +17,7 @@ namespace crypto { class DiffieHellman : public BaseObject { public: static void Initialize(Environment* env, v8::Local target); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); bool Init(int primeLength, int g); bool Init(const char* p, int p_len, int g); diff --git a/src/crypto/crypto_dsa.cc b/src/crypto/crypto_dsa.cc index 271db427fa8539..c7894baf00ee9c 100644 --- a/src/crypto/crypto_dsa.cc +++ b/src/crypto/crypto_dsa.cc @@ -167,6 +167,11 @@ void Initialize(Environment* env, Local target) { DsaKeyPairGenJob::Initialize(env, target); DSAKeyExportJob::Initialize(env, target); } + +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + DsaKeyPairGenJob::RegisterExternalReferences(registry); + DSAKeyExportJob::RegisterExternalReferences(registry); +} } // namespace DSAAlg } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_dsa.h b/src/crypto/crypto_dsa.h index 647b4d9004e8cb..e93cb8075c239b 100644 --- a/src/crypto/crypto_dsa.h +++ b/src/crypto/crypto_dsa.h @@ -68,6 +68,7 @@ v8::Maybe GetDsaKeyDetail( namespace DSAAlg { void Initialize(Environment* env, v8::Local target); +void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace DSAAlg } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_ec.cc b/src/crypto/crypto_ec.cc index 2abe570080e21d..868c3465ad33d1 100644 --- a/src/crypto/crypto_ec.cc +++ b/src/crypto/crypto_ec.cc @@ -83,6 +83,22 @@ void ECDH::Initialize(Environment* env, Local target) { NODE_DEFINE_CONSTANT(target, OPENSSL_EC_EXPLICIT_CURVE); } +void ECDH::RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(New); + registry->Register(GenerateKeys); + registry->Register(ComputeSecret); + registry->Register(GetPublicKey); + registry->Register(GetPrivateKey); + registry->Register(SetPublicKey); + registry->Register(SetPrivateKey); + registry->Register(ECDH::ConvertKey); + registry->Register(ECDH::GetCurves); + + ECDHBitsJob::RegisterExternalReferences(registry); + ECKeyPairGenJob::RegisterExternalReferences(registry); + ECKeyExportJob::RegisterExternalReferences(registry); +} + void ECDH::GetCurves(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); const size_t num_curves = EC_get_builtin_curves(nullptr, 0); diff --git a/src/crypto/crypto_ec.h b/src/crypto/crypto_ec.h index 317ee877a12b6b..34d37c7e44220d 100644 --- a/src/crypto/crypto_ec.h +++ b/src/crypto/crypto_ec.h @@ -24,6 +24,8 @@ class ECDH final : public BaseObject { ~ECDH() override; 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); diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index ba2c52268a23ff..e4c4fc61815a1f 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -57,6 +57,15 @@ void Hash::Initialize(Environment* env, Local target) { HashJob::Initialize(env, target); } +void Hash::RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(New); + registry->Register(HashUpdate); + registry->Register(HashDigest); + registry->Register(GetHashes); + + HashJob::RegisterExternalReferences(registry); +} + void Hash::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); diff --git a/src/crypto/crypto_hash.h b/src/crypto/crypto_hash.h index 9f004d1dda6ea5..cfc09334ce0195 100644 --- a/src/crypto/crypto_hash.h +++ b/src/crypto/crypto_hash.h @@ -16,6 +16,7 @@ namespace crypto { class Hash final : public BaseObject { public: static void Initialize(Environment* env, v8::Local target); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(Hash) diff --git a/src/crypto/crypto_hmac.cc b/src/crypto/crypto_hmac.cc index 055541196d26e1..38503ac8ac33d4 100644 --- a/src/crypto/crypto_hmac.cc +++ b/src/crypto/crypto_hmac.cc @@ -53,6 +53,14 @@ void Hmac::Initialize(Environment* env, Local target) { HmacJob::Initialize(env, target); } +void Hmac::RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(New); + registry->Register(HmacInit); + registry->Register(HmacUpdate); + registry->Register(HmacDigest); + HmacJob::RegisterExternalReferences(registry); +} + void Hmac::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); new Hmac(env, args.This()); diff --git a/src/crypto/crypto_hmac.h b/src/crypto/crypto_hmac.h index d7427ce883c2e1..c37fc4a82c6e95 100644 --- a/src/crypto/crypto_hmac.h +++ b/src/crypto/crypto_hmac.h @@ -17,6 +17,7 @@ namespace crypto { class Hmac : public BaseObject { public: static void Initialize(Environment* env, v8::Local target); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(Hmac) diff --git a/src/crypto/crypto_keygen.cc b/src/crypto/crypto_keygen.cc index b08ca3b2f513d6..24943883b7ba0a 100644 --- a/src/crypto/crypto_keygen.cc +++ b/src/crypto/crypto_keygen.cc @@ -104,6 +104,12 @@ void Initialize(Environment* env, Local target) { NidKeyPairGenJob::Initialize(env, target); SecretKeyGenJob::Initialize(env, target); } + +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + NidKeyPairGenJob::RegisterExternalReferences(registry); + SecretKeyGenJob::RegisterExternalReferences(registry); +} + } // namespace Keygen } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_keygen.h b/src/crypto/crypto_keygen.h index 532bcdb80c78cf..d4790097419044 100644 --- a/src/crypto/crypto_keygen.h +++ b/src/crypto/crypto_keygen.h @@ -16,6 +16,7 @@ namespace node { namespace crypto { namespace Keygen { void Initialize(Environment* env, v8::Local target); +void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace Keygen enum class KeyGenJobStatus { @@ -58,6 +59,10 @@ class KeyGenJob final : public CryptoJob { CryptoJob::Initialize(New, env, target); } + static void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + CryptoJob::RegisterExternalReferences(New, registry); + } + KeyGenJob( Environment* env, v8::Local object, diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index 3243ece8670ce2..c5b3e6b37183fd 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -927,6 +927,20 @@ v8::Local KeyObjectHandle::Initialize(Environment* env) { return function; } +void KeyObjectHandle::RegisterExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(New); + registry->Register(Init); + registry->Register(GetSymmetricKeySize); + registry->Register(GetAsymmetricKeyType); + registry->Register(Export); + registry->Register(ExportJWK); + registry->Register(InitECRaw); + registry->Register(InitEDRaw); + registry->Register(InitJWK); + registry->Register(GetKeyDetail); +} + MaybeLocal KeyObjectHandle::Create( Environment* env, std::shared_ptr data) { @@ -1256,6 +1270,12 @@ void NativeKeyObject::Initialize(Environment* env, Local target) { NativeKeyObject::CreateNativeKeyObjectClass); } +void NativeKeyObject::RegisterExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(NativeKeyObject::CreateNativeKeyObjectClass); + registry->Register(NativeKeyObject::New); +} + void NativeKeyObject::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CHECK_EQ(args.Length(), 1); @@ -1405,6 +1425,10 @@ void Initialize(Environment* env, Local target) { NODE_DEFINE_CONSTANT(target, kSigEncDER); NODE_DEFINE_CONSTANT(target, kSigEncP1363); } + +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + KeyObjectHandle::RegisterExternalReferences(registry); +} } // namespace Keys } // namespace crypto diff --git a/src/crypto/crypto_keys.h b/src/crypto/crypto_keys.h index df3ab8ab181437..48d38cd20b0899 100644 --- a/src/crypto/crypto_keys.h +++ b/src/crypto/crypto_keys.h @@ -169,6 +169,7 @@ class KeyObjectData : public MemoryRetainer { class KeyObjectHandle : public BaseObject { public: static v8::Local Initialize(Environment* env); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); static v8::MaybeLocal Create(Environment* env, std::shared_ptr data); @@ -216,6 +217,7 @@ class KeyObjectHandle : public BaseObject { class NativeKeyObject : public BaseObject { public: static void Initialize(Environment* env, v8::Local target); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); static void New(const v8::FunctionCallbackInfo& args); static void CreateNativeKeyObjectClass( @@ -316,6 +318,10 @@ class KeyExportJob final : public CryptoJob { CryptoJob::Initialize(New, env, target); } + static void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + CryptoJob::RegisterExternalReferences(New, registry); + } + KeyExportJob( Environment* env, v8::Local object, @@ -403,6 +409,7 @@ WebCryptoKeyExportStatus PKEY_PKCS8_Export( namespace Keys { void Initialize(Environment* env, v8::Local target); +void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace Keys } // namespace crypto diff --git a/src/crypto/crypto_random.cc b/src/crypto/crypto_random.cc index 7cb4513f9ad0ea..fc88deb460314c 100644 --- a/src/crypto/crypto_random.cc +++ b/src/crypto/crypto_random.cc @@ -246,6 +246,12 @@ void Initialize(Environment* env, Local target) { RandomPrimeJob::Initialize(env, target); CheckPrimeJob::Initialize(env, target); } + +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + RandomBytesJob::RegisterExternalReferences(registry); + RandomPrimeJob::RegisterExternalReferences(registry); + CheckPrimeJob::RegisterExternalReferences(registry); +} } // namespace Random } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_random.h b/src/crypto/crypto_random.h index c9a827f6171e15..970306c30cd8e3 100644 --- a/src/crypto/crypto_random.h +++ b/src/crypto/crypto_random.h @@ -122,6 +122,7 @@ using CheckPrimeJob = DeriveBitsJob; namespace Random { void Initialize(Environment* env, v8::Local target); +void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace Random } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index d2307c33f5de87..ae4550e9fde812 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -651,6 +651,12 @@ void Initialize(Environment* env, Local target) { NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_PSS); NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_OAEP); } + +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + RSAKeyPairGenJob::RegisterExternalReferences(registry); + RSAKeyExportJob::RegisterExternalReferences(registry); + RSACipherJob::RegisterExternalReferences(registry); +} } // namespace RSAAlg } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_rsa.h b/src/crypto/crypto_rsa.h index 978f2f3455d2d4..4f6fbad4f6e6b0 100644 --- a/src/crypto/crypto_rsa.h +++ b/src/crypto/crypto_rsa.h @@ -133,6 +133,7 @@ v8::Maybe GetRsaKeyDetail( namespace RSAAlg { void Initialize(Environment* env, v8::Local target); +void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace RSAAlg } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_sig.cc b/src/crypto/crypto_sig.cc index 7846df17ffbe8b..be2b3c32d98254 100644 --- a/src/crypto/crypto_sig.cc +++ b/src/crypto/crypto_sig.cc @@ -345,6 +345,14 @@ void Sign::Initialize(Environment* env, Local target) { NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING); } +void Sign::RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(New); + registry->Register(SignInit); + registry->Register(SignUpdate); + registry->Register(SignFinal); + SignJob::RegisterExternalReferences(registry); +} + void Sign::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); new Sign(env, args.This()); @@ -452,6 +460,13 @@ void Verify::Initialize(Environment* env, Local target) { env->SetConstructorFunction(target, "Verify", t); } +void Verify::RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(New); + registry->Register(VerifyInit); + registry->Register(VerifyUpdate); + registry->Register(VerifyFinal); +} + void Verify::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); new Verify(env, args.This()); diff --git a/src/crypto/crypto_sig.h b/src/crypto/crypto_sig.h index 5f9104fc5d3c00..eb643685c0bdde 100644 --- a/src/crypto/crypto_sig.h +++ b/src/crypto/crypto_sig.h @@ -49,6 +49,7 @@ class SignBase : public BaseObject { class Sign : public SignBase { public: static void Initialize(Environment* env, v8::Local target); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); struct SignResult { Error error; @@ -80,6 +81,7 @@ class Sign : public SignBase { class Verify : public SignBase { public: static void Initialize(Environment* env, v8::Local target); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); Error VerifyFinal(const ManagedEVPPKey& key, const ByteSource& sig, diff --git a/src/crypto/crypto_spkac.cc b/src/crypto/crypto_spkac.cc index 6950a0390377e8..db58fe4a11b4ad 100644 --- a/src/crypto/crypto_spkac.cc +++ b/src/crypto/crypto_spkac.cc @@ -125,6 +125,11 @@ void Initialize(Environment* env, Local target) { env->SetMethodNoSideEffect(target, "certExportChallenge", ExportChallenge); } +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(VerifySpkac); + registry->Register(ExportPublicKey); + registry->Register(ExportChallenge); +} } // namespace SPKAC } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_spkac.h b/src/crypto/crypto_spkac.h index ed204c81337716..bdd9f6b35c7a16 100644 --- a/src/crypto/crypto_spkac.h +++ b/src/crypto/crypto_spkac.h @@ -12,6 +12,7 @@ namespace node { namespace crypto { namespace SPKAC { void Initialize(Environment* env, v8::Local); +void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace SPKAC } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_timing.cc b/src/crypto/crypto_timing.cc index 0a9b167223b846..3cc1a12ec009d6 100644 --- a/src/crypto/crypto_timing.cc +++ b/src/crypto/crypto_timing.cc @@ -49,6 +49,9 @@ void TimingSafeEqual(const FunctionCallbackInfo& args) { void Initialize(Environment* env, Local target) { env->SetMethodNoSideEffect(target, "timingSafeEqual", TimingSafeEqual); } +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(TimingSafeEqual); +} } // namespace Timing } // namespace crypto diff --git a/src/crypto/crypto_timing.h b/src/crypto/crypto_timing.h index a164650861978c..3e0594ce3ecc51 100644 --- a/src/crypto/crypto_timing.h +++ b/src/crypto/crypto_timing.h @@ -10,7 +10,7 @@ namespace node { namespace crypto { namespace Timing { void Initialize(Environment* env, v8::Local target); - +void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace Timing } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index 3b646160800082..23bc2f21493dc1 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -2100,7 +2100,59 @@ void TLSWrap::Initialize( target->Set(env->context(), tlsWrapString, fn).Check(); } +void TLSWrap::RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(TLSWrap::Wrap); + registry->Register(GetWriteQueueSize); + + registry->Register(CertCbDone); + registry->Register(DestroySSL); + registry->Register(EnableCertCb); + registry->Register(EndParser); + registry->Register(EnableKeylogCallback); + registry->Register(EnableSessionCallbacks); + registry->Register(EnableTrace); + registry->Register(GetServername); + registry->Register(LoadSession); + registry->Register(NewSessionDone); + registry->Register(Receive); + registry->Register(Renegotiate); + registry->Register(RequestOCSP); + registry->Register(SetALPNProtocols); + registry->Register(SetOCSPResponse); + registry->Register(SetServername); + registry->Register(SetSession); + registry->Register(SetVerifyMode); + registry->Register(Start); + registry->Register(ExportKeyingMaterial); + registry->Register(IsSessionReused); + registry->Register(GetALPNNegotiatedProto); + registry->Register(GetCertificate); + registry->Register(GetX509Certificate); + registry->Register(GetCipher); + registry->Register(GetEphemeralKeyInfo); + registry->Register(GetFinished); + registry->Register(GetPeerCertificate); + registry->Register(GetPeerX509Certificate); + registry->Register(GetPeerFinished); + registry->Register(GetProtocol); + registry->Register(GetSession); + registry->Register(GetSharedSigalgs); + registry->Register(GetTLSTicket); + registry->Register(VerifyError); + +#ifdef SSL_set_max_send_fragment + registry->Register(SetMaxSendFragment); +#endif // SSL_set_max_send_fragment + +#ifndef OPENSSL_NO_PSK + registry->Register(EnablePskCallback); + registry->Register(SetPskIdentityHint); +#endif // !OPENSSL_NO_PSK +} + } // namespace crypto } // namespace node NODE_MODULE_CONTEXT_AWARE_INTERNAL(tls_wrap, node::crypto::TLSWrap::Initialize) +NODE_MODULE_EXTERNAL_REFERENCE( + tls_wrap, node::crypto::TLSWrap::RegisterExternalReferences) diff --git a/src/crypto/crypto_tls.h b/src/crypto/crypto_tls.h index 6dda31d22be8a6..c4cf4c60e8e51d 100644 --- a/src/crypto/crypto_tls.h +++ b/src/crypto/crypto_tls.h @@ -52,6 +52,7 @@ class TLSWrap : public AsyncWrap, v8::Local unused, v8::Local context, void* priv); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); ~TLSWrap() override; diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc index 796ea3025e4100..d175566d603691 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -38,6 +38,7 @@ using v8::NewStringType; using v8::Nothing; using v8::Object; using v8::String; +using v8::TryCatch; using v8::Uint32; using v8::Uint8Array; using v8::Value; @@ -124,6 +125,17 @@ bool ProcessFipsOptions() { return true; } +bool InitCryptoOnce(Isolate* isolate) { + static uv_once_t init_once = UV_ONCE_INIT; + TryCatch try_catch{isolate}; + uv_once(&init_once, InitCryptoOnce); + if (try_catch.HasCaught() && !try_catch.HasTerminated()) { + try_catch.ReThrow(); + return false; + } + return true; +} + void InitCryptoOnce() { #ifndef OPENSSL_IS_BORINGSSL OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new(); @@ -721,6 +733,18 @@ void Initialize(Environment* env, Local target) { env->SetMethod(target, "secureBuffer", SecureBuffer); env->SetMethod(target, "secureHeapUsed", SecureHeapUsed); } +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { +#ifndef OPENSSL_NO_ENGINE + registry->Register(SetEngine); +#endif // !OPENSSL_NO_ENGINE + + registry->Register(GetFipsCrypto); + registry->Register(SetFipsCrypto); + registry->Register(TestFipsCrypto); + registry->Register(SecureBuffer); + registry->Register(SecureHeapUsed); +} + } // namespace Util } // namespace crypto diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index 9606c29097dfc0..463a19f516d23f 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -7,6 +7,7 @@ #include "async_wrap.h" #include "allocated_buffer.h" #include "node_errors.h" +#include "node_external_reference.h" #include "node_internals.h" #include "util.h" #include "v8.h" @@ -88,6 +89,7 @@ extern int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx); bool ProcessFipsOptions(); +bool InitCryptoOnce(v8::Isolate* isolate); void InitCryptoOnce(); void InitCrypto(v8::Local target); @@ -423,6 +425,12 @@ class CryptoJob : public AsyncWrap, public ThreadPoolWork { env->SetConstructorFunction(target, CryptoJobTraits::JobName, job); } + static void RegisterExternalReferences(v8::FunctionCallback new_fn, + ExternalReferenceRegistry* registry) { + registry->Register(new_fn); + registry->Register(Run); + } + private: const CryptoJobMode mode_; CryptoErrorStore errors_; @@ -457,6 +465,10 @@ class DeriveBitsJob final : public CryptoJob { CryptoJob::Initialize(New, env, target); } + static void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + CryptoJob::RegisterExternalReferences(New, registry); + } + DeriveBitsJob( Environment* env, v8::Local object, @@ -730,6 +742,7 @@ v8::Maybe SetEncodedValue( namespace Util { void Initialize(Environment* env, v8::Local target); +void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace Util } // namespace crypto diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc index 574a3a194de82f..cb34003c4dded8 100644 --- a/src/crypto/crypto_x509.cc +++ b/src/crypto/crypto_x509.cc @@ -536,5 +536,31 @@ void X509Certificate::Initialize(Environment* env, Local target) { NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); } +void X509Certificate::RegisterExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(X509Certificate::Parse); + registry->Register(Subject); + registry->Register(SubjectAltName); + registry->Register(InfoAccess); + registry->Register(Issuer); + registry->Register(ValidTo); + registry->Register(ValidFrom); + registry->Register(Fingerprint); + registry->Register(Fingerprint256); + registry->Register(KeyUsage); + registry->Register(SerialNumber); + registry->Register(Pem); + registry->Register(Raw); + registry->Register(PublicKey); + registry->Register(CheckCA); + registry->Register(CheckHost); + registry->Register(CheckEmail); + registry->Register(CheckIP); + registry->Register(CheckIssued); + registry->Register(CheckPrivateKey); + registry->Register(Verify); + registry->Register(ToLegacy); + registry->Register(GetIssuerCert); +} } // namespace crypto } // namespace node diff --git a/src/crypto/crypto_x509.h b/src/crypto/crypto_x509.h index 05bfb6e7cb3e20..cd7f529b476dae 100644 --- a/src/crypto/crypto_x509.h +++ b/src/crypto/crypto_x509.h @@ -43,6 +43,7 @@ class X509Certificate : public BaseObject { }; static void Initialize(Environment* env, v8::Local target); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); static v8::Local GetConstructorTemplate( Environment* env); static bool HasInstance(Environment* env, v8::Local object); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index b37e47d35b9a92..8563b14036c2af 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -22,8 +22,9 @@ #include "node_crypto.h" #include "async_wrap-inl.h" #include "debug_utils-inl.h" -#include "threadpoolwork-inl.h" #include "memory_tracker-inl.h" +#include "node_external_reference.h" +#include "threadpoolwork-inl.h" #include "v8.h" namespace node { @@ -36,48 +37,63 @@ using v8::Value; namespace crypto { +#define CRYPTO_NAMESPACE_LIST_BASE(V) \ + V(AES) \ + V(CipherBase) \ + V(DiffieHellman) \ + V(DSAAlg) \ + V(ECDH) \ + V(Hash) \ + V(HKDFJob) \ + V(Hmac) \ + V(Keygen) \ + V(Keys) \ + V(NativeKeyObject) \ + V(PBKDF2Job) \ + V(Random) \ + V(RSAAlg) \ + V(SecureContext) \ + V(Sign) \ + V(SPKAC) \ + V(Timing) \ + V(Util) \ + V(Verify) \ + V(X509Certificate) + +#ifdef OPENSSL_NO_SCRYPT +#define SCRYPT_NAMESPACE_LIST(V) +#else +#define SCRYPT_NAMESPACE_LIST(V) V(ScryptJob) +#endif // OPENSSL_NO_SCRYPT + +#define CRYPTO_NAMESPACE_LIST(V) \ + CRYPTO_NAMESPACE_LIST_BASE(V) \ + SCRYPT_NAMESPACE_LIST(V) + void Initialize(Local target, Local unused, Local context, void* priv) { Environment* env = Environment::GetCurrent(context); - static uv_once_t init_once = UV_ONCE_INIT; - TryCatch try_catch{env->isolate()}; - uv_once(&init_once, InitCryptoOnce); - if (try_catch.HasCaught() && !try_catch.HasTerminated()) { - try_catch.ReThrow(); + // TODO(joyeecheung): this needs to be called again if the instance is + // deserialized from a snapshot with the crypto bindings. + if (!InitCryptoOnce(env->isolate())) { return; } - AES::Initialize(env, target); - CipherBase::Initialize(env, target); - DiffieHellman::Initialize(env, target); - DSAAlg::Initialize(env, target); - ECDH::Initialize(env, target); - Hash::Initialize(env, target); - HKDFJob::Initialize(env, target); - Hmac::Initialize(env, target); - Keygen::Initialize(env, target); - Keys::Initialize(env, target); - NativeKeyObject::Initialize(env, target); - PBKDF2Job::Initialize(env, target); - Random::Initialize(env, target); - RSAAlg::Initialize(env, target); - SecureContext::Initialize(env, target); - Sign::Initialize(env, target); - SPKAC::Initialize(env, target); - Timing::Initialize(env, target); - Util::Initialize(env, target); - Verify::Initialize(env, target); - X509Certificate::Initialize(env, target); - -#ifndef OPENSSL_NO_SCRYPT - ScryptJob::Initialize(env, target); -#endif +#define V(Namespace) Namespace::Initialize(env, target); + CRYPTO_NAMESPACE_LIST(V) +#undef V } +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { +#define V(Namespace) Namespace::RegisterExternalReferences(registry); + CRYPTO_NAMESPACE_LIST(V) +#undef V +} } // namespace crypto } // namespace node NODE_MODULE_CONTEXT_AWARE_INTERNAL(crypto, node::crypto::Initialize) +NODE_MODULE_EXTERNAL_REFERENCE(crypto, node::crypto::RegisterExternalReferences) diff --git a/src/node_external_reference.h b/src/node_external_reference.h index f51999e996fd06..7da15290a15e67 100644 --- a/src/node_external_reference.h +++ b/src/node_external_reference.h @@ -104,11 +104,18 @@ class ExternalReferenceRegistry { #define EXTERNAL_REFERENCE_BINDING_LIST_DTRACE(V) #endif +#if HAVE_OPENSSL +#define EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V) V(crypto) V(tls_wrap) +#else +#define EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V) +#endif // HAVE_OPENSSL + #define EXTERNAL_REFERENCE_BINDING_LIST(V) \ EXTERNAL_REFERENCE_BINDING_LIST_BASE(V) \ EXTERNAL_REFERENCE_BINDING_LIST_INSPECTOR(V) \ EXTERNAL_REFERENCE_BINDING_LIST_I18N(V) \ - EXTERNAL_REFERENCE_BINDING_LIST_DTRACE(V) + EXTERNAL_REFERENCE_BINDING_LIST_DTRACE(V) \ + EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V) } // namespace node