Skip to content

Commit

Permalink
src: refactor SecureContext Initialization
Browse files Browse the repository at this point in the history
Extracts out SecureContext::GetConstructorFunction, adds
SecureContext::HasInstance and SecureContext::Create in
preparation for re-adding QUIC

Signed-off-by: James M Snell <jasnell@gmail.com>

PR-URL: #38116
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
jasnell committed Apr 12, 2021
1 parent eb20447 commit 6c9b19a
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 64 deletions.
156 changes: 92 additions & 64 deletions src/crypto/crypto_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -247,72 +247,89 @@ void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
Array::New(env->isolate(), result, arraysize(root_certs)));
}

void SecureContext::Initialize(Environment* env, Local<Object> target) {
Local<FunctionTemplate> 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<true>);
env->SetProtoMethodNoSideEffect(t, "getIssuer", GetCertificate<false>);

#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<FunctionTemplate> ctx_getter_templ =
FunctionTemplate::New(env->isolate(),
CtxGetter,
Local<Value>(),
Signature::New(env->isolate(), t));


t->PrototypeTemplate()->SetAccessorProperty(
FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
ctx_getter_templ,
Local<FunctionTemplate>(),
static_cast<PropertyAttribute>(ReadOnly | DontDelete));
bool SecureContext::HasInstance(Environment* env, const Local<Value>& value) {
return GetConstructorTemplate(env)->HasInstance(value);
}

env->SetConstructorFunction(target, "SecureContext", t);
Local<FunctionTemplate> SecureContext::GetConstructorTemplate(
Environment* env) {
Local<FunctionTemplate> 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<true>);
env->SetProtoMethodNoSideEffect(tmpl, "getIssuer",
GetCertificate<false>);

#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<FunctionTemplate> ctx_getter_templ =
FunctionTemplate::New(env->isolate(),
CtxGetter,
Local<Value>(),
Signature::New(env->isolate(), tmpl));

tmpl->PrototypeTemplate()->SetAccessorProperty(
FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
ctx_getter_templ,
Local<FunctionTemplate>(),
static_cast<PropertyAttribute>(ReadOnly | DontDelete));

env->set_secure_context_constructor_template(tmpl);
}
return tmpl;
}

env->set_secure_context_constructor_template(t);
void SecureContext::Initialize(Environment* env, Local<Object> target) {
env->SetConstructorFunction(
target,
"SecureContext",
GetConstructorTemplate(env),
Environment::SetConstructorFunctionFlag::NONE);

env->SetMethodNoSideEffect(target, "getRootCertificates",
GetRootCertificates);
Expand All @@ -321,6 +338,17 @@ void SecureContext::Initialize(Environment* env, Local<Object> target) {
IsExtraRootCertsFileLoaded);
}

SecureContext* SecureContext::Create(Environment* env) {
Local<Object> obj;
if (!GetConstructorTemplate(env)
->InstanceTemplate()
->NewInstance(env->context()).ToLocal(&obj)) {
return nullptr;
}

return new SecureContext(env, obj);
}

SecureContext::SecureContext(Environment* env, Local<Object> wrap)
: BaseObject(env, wrap) {
MakeWeak();
Expand Down
4 changes: 4 additions & 0 deletions src/crypto/crypto_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ class SecureContext final : public BaseObject {

~SecureContext() override;

static bool HasInstance(Environment* env, const v8::Local<v8::Value>& value);
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
Environment* env);
static void Initialize(Environment* env, v8::Local<v8::Object> target);
static SecureContext* Create(Environment* env);

SSL_CTX* operator*() const { return ctx_.get(); }

Expand Down
1 change: 1 addition & 0 deletions src/node_native_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ void NativeModuleLoader::InitializeModuleCategories() {
"tls",
"_tls_common",
"_tls_wrap",
"internal/tls",
"internal/http2/core",
"internal/http2/compat",
"internal/policy/manifest",
Expand Down

0 comments on commit 6c9b19a

Please sign in to comment.