From 6c9b19a7af5c20b5b07a55e239e992a5bff553b3 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 6 Apr 2021 13:54:07 -0700 Subject: [PATCH] src: refactor SecureContext Initialization Extracts out SecureContext::GetConstructorFunction, adds SecureContext::HasInstance and SecureContext::Create in preparation for re-adding QUIC Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/38116 Reviewed-By: Anna Henningsen Reviewed-By: Matteo Collina --- src/crypto/crypto_context.cc | 156 +++++++++++++++++++++-------------- src/crypto/crypto_context.h | 4 + src/node_native_module.cc | 1 + 3 files changed, 97 insertions(+), 64 deletions(-) diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index 80f04efbed0f17..8feefde819ea8b 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -247,72 +247,89 @@ void GetRootCertificates(const FunctionCallbackInfo& args) { Array::New(env->isolate(), result, arraysize(root_certs))); } -void SecureContext::Initialize(Environment* env, Local target) { - Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount( - SecureContext::kInternalFieldCount); - t->Inherit(BaseObject::GetConstructorTemplate(env)); - - env->SetProtoMethod(t, "init", Init); - env->SetProtoMethod(t, "setKey", SetKey); -#ifndef OPENSSL_NO_ENGINE - env->SetProtoMethod(t, "setEngineKey", SetEngineKey); -#endif // !OPENSSL_NO_ENGINE - env->SetProtoMethod(t, "setCert", SetCert); - env->SetProtoMethod(t, "addCACert", AddCACert); - env->SetProtoMethod(t, "addCRL", AddCRL); - env->SetProtoMethod(t, "addRootCerts", AddRootCerts); - env->SetProtoMethod(t, "setCipherSuites", SetCipherSuites); - env->SetProtoMethod(t, "setCiphers", SetCiphers); - env->SetProtoMethod(t, "setSigalgs", SetSigalgs); - env->SetProtoMethod(t, "setECDHCurve", SetECDHCurve); - env->SetProtoMethod(t, "setDHParam", SetDHParam); - env->SetProtoMethod(t, "setMaxProto", SetMaxProto); - env->SetProtoMethod(t, "setMinProto", SetMinProto); - env->SetProtoMethod(t, "getMaxProto", GetMaxProto); - env->SetProtoMethod(t, "getMinProto", GetMinProto); - env->SetProtoMethod(t, "setOptions", SetOptions); - env->SetProtoMethod(t, "setSessionIdContext", SetSessionIdContext); - env->SetProtoMethod(t, "setSessionTimeout", SetSessionTimeout); - env->SetProtoMethod(t, "close", Close); - env->SetProtoMethod(t, "loadPKCS12", LoadPKCS12); -#ifndef OPENSSL_NO_ENGINE - env->SetProtoMethod(t, "setClientCertEngine", SetClientCertEngine); -#endif // !OPENSSL_NO_ENGINE - env->SetProtoMethodNoSideEffect(t, "getTicketKeys", GetTicketKeys); - env->SetProtoMethod(t, "setTicketKeys", SetTicketKeys); - env->SetProtoMethod(t, "setFreeListLength", SetFreeListLength); - env->SetProtoMethod(t, "enableTicketKeyCallback", EnableTicketKeyCallback); - env->SetProtoMethodNoSideEffect(t, "getCertificate", GetCertificate); - env->SetProtoMethodNoSideEffect(t, "getIssuer", GetCertificate); - -#define SET_INTEGER_CONSTANTS(name, value) \ - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), name), \ - Integer::NewFromUnsigned(env->isolate(), value)); - SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex); - SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex); - SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex); - SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex); - SET_INTEGER_CONSTANTS("kTicketKeyIVIndex", kTicketKeyIVIndex); - -#undef SET_INTEGER_CONSTANTS - - Local ctx_getter_templ = - FunctionTemplate::New(env->isolate(), - CtxGetter, - Local(), - Signature::New(env->isolate(), t)); - - - t->PrototypeTemplate()->SetAccessorProperty( - FIXED_ONE_BYTE_STRING(env->isolate(), "_external"), - ctx_getter_templ, - Local(), - static_cast(ReadOnly | DontDelete)); +bool SecureContext::HasInstance(Environment* env, const Local& value) { + return GetConstructorTemplate(env)->HasInstance(value); +} - env->SetConstructorFunction(target, "SecureContext", t); +Local SecureContext::GetConstructorTemplate( + Environment* env) { + Local tmpl = env->secure_context_constructor_template(); + if (tmpl.IsEmpty()) { + tmpl = env->NewFunctionTemplate(New); + tmpl->InstanceTemplate()->SetInternalFieldCount( + SecureContext::kInternalFieldCount); + tmpl->Inherit(BaseObject::GetConstructorTemplate(env)); + tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext")); + + env->SetProtoMethod(tmpl, "init", Init); + env->SetProtoMethod(tmpl, "setKey", SetKey); + env->SetProtoMethod(tmpl, "setCert", SetCert); + env->SetProtoMethod(tmpl, "addCACert", AddCACert); + env->SetProtoMethod(tmpl, "addCRL", AddCRL); + env->SetProtoMethod(tmpl, "addRootCerts", AddRootCerts); + env->SetProtoMethod(tmpl, "setCipherSuites", SetCipherSuites); + env->SetProtoMethod(tmpl, "setCiphers", SetCiphers); + env->SetProtoMethod(tmpl, "setSigalgs", SetSigalgs); + env->SetProtoMethod(tmpl, "setECDHCurve", SetECDHCurve); + env->SetProtoMethod(tmpl, "setDHParam", SetDHParam); + env->SetProtoMethod(tmpl, "setMaxProto", SetMaxProto); + env->SetProtoMethod(tmpl, "setMinProto", SetMinProto); + env->SetProtoMethod(tmpl, "getMaxProto", GetMaxProto); + env->SetProtoMethod(tmpl, "getMinProto", GetMinProto); + env->SetProtoMethod(tmpl, "setOptions", SetOptions); + env->SetProtoMethod(tmpl, "setSessionIdContext", SetSessionIdContext); + env->SetProtoMethod(tmpl, "setSessionTimeout", SetSessionTimeout); + env->SetProtoMethod(tmpl, "close", Close); + env->SetProtoMethod(tmpl, "loadPKCS12", LoadPKCS12); + env->SetProtoMethod(tmpl, "setTicketKeys", SetTicketKeys); + env->SetProtoMethod(tmpl, "setFreeListLength", SetFreeListLength); + env->SetProtoMethod(tmpl, "enableTicketKeyCallback", + EnableTicketKeyCallback); + + env->SetProtoMethodNoSideEffect(tmpl, "getTicketKeys", GetTicketKeys); + env->SetProtoMethodNoSideEffect(tmpl, "getCertificate", + GetCertificate); + env->SetProtoMethodNoSideEffect(tmpl, "getIssuer", + GetCertificate); + + #ifndef OPENSSL_NO_ENGINE + env->SetProtoMethod(tmpl, "setEngineKey", SetEngineKey); + env->SetProtoMethod(tmpl, "setClientCertEngine", SetClientCertEngine); + #endif // !OPENSSL_NO_ENGINE + + #define SET_INTEGER_CONSTANTS(name, value) \ + tmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), name), \ + Integer::NewFromUnsigned(env->isolate(), value)); + SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex); + SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex); + SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex); + SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex); + SET_INTEGER_CONSTANTS("kTicketKeyIVIndex", kTicketKeyIVIndex); + #undef SET_INTEGER_CONSTANTS + + Local ctx_getter_templ = + FunctionTemplate::New(env->isolate(), + CtxGetter, + Local(), + Signature::New(env->isolate(), tmpl)); + + tmpl->PrototypeTemplate()->SetAccessorProperty( + FIXED_ONE_BYTE_STRING(env->isolate(), "_external"), + ctx_getter_templ, + Local(), + static_cast(ReadOnly | DontDelete)); + + env->set_secure_context_constructor_template(tmpl); + } + return tmpl; +} - env->set_secure_context_constructor_template(t); +void SecureContext::Initialize(Environment* env, Local target) { + env->SetConstructorFunction( + target, + "SecureContext", + GetConstructorTemplate(env), + Environment::SetConstructorFunctionFlag::NONE); env->SetMethodNoSideEffect(target, "getRootCertificates", GetRootCertificates); @@ -321,6 +338,17 @@ void SecureContext::Initialize(Environment* env, Local target) { IsExtraRootCertsFileLoaded); } +SecureContext* SecureContext::Create(Environment* env) { + Local obj; + if (!GetConstructorTemplate(env) + ->InstanceTemplate() + ->NewInstance(env->context()).ToLocal(&obj)) { + return nullptr; + } + + return new SecureContext(env, obj); +} + SecureContext::SecureContext(Environment* env, Local wrap) : BaseObject(env, wrap) { MakeWeak(); diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h index bea75f31d4a44e..b857019e47e188 100644 --- a/src/crypto/crypto_context.h +++ b/src/crypto/crypto_context.h @@ -34,7 +34,11 @@ class SecureContext final : public BaseObject { ~SecureContext() override; + static bool HasInstance(Environment* env, const v8::Local& value); + static v8::Local GetConstructorTemplate( + Environment* env); static void Initialize(Environment* env, v8::Local target); + static SecureContext* Create(Environment* env); SSL_CTX* operator*() const { return ctx_.get(); } diff --git a/src/node_native_module.cc b/src/node_native_module.cc index 9c478cb6dfbcf0..b3a104547f392d 100644 --- a/src/node_native_module.cc +++ b/src/node_native_module.cc @@ -98,6 +98,7 @@ void NativeModuleLoader::InitializeModuleCategories() { "tls", "_tls_common", "_tls_wrap", + "internal/tls", "internal/http2/core", "internal/http2/compat", "internal/policy/manifest",