@@ -471,6 +471,9 @@ void SecureContext::Initialize(Environment* env, Local<Object> target) {
471471
472472 env->SetProtoMethod (t, " init" , Init);
473473 env->SetProtoMethod (t, " setKey" , SetKey);
474+ #ifndef OPENSSL_NO_ENGINE
475+ env->SetProtoMethod (t, " setEngineKey" , SetEngineKey);
476+ #endif // !OPENSSL_NO_ENGINE
474477 env->SetProtoMethod (t, " setCert" , SetCert);
475478 env->SetProtoMethod (t, " addCACert" , AddCACert);
476479 env->SetProtoMethod (t, " addCRL" , AddCRL);
@@ -764,6 +767,56 @@ void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) {
764767 }
765768}
766769
770+ #ifndef OPENSSL_NO_ENGINE
771+ // Helpers for the smart pointer.
772+ void ENGINE_free_fn (ENGINE* engine) { ENGINE_free (engine); }
773+
774+ void ENGINE_finish_and_free_fn (ENGINE* engine) {
775+ ENGINE_finish (engine);
776+ ENGINE_free (engine);
777+ }
778+
779+ void SecureContext::SetEngineKey (const FunctionCallbackInfo<Value>& args) {
780+ Environment* env = Environment::GetCurrent (args);
781+
782+ SecureContext* sc;
783+ ASSIGN_OR_RETURN_UNWRAP (&sc, args.Holder ());
784+
785+ CHECK_EQ (args.Length (), 2 );
786+
787+ char errmsg[1024 ];
788+ const node::Utf8Value engine_id (env->isolate (), args[1 ]);
789+ std::unique_ptr<ENGINE, std::function<void (ENGINE*)>> e =
790+ { LoadEngineById (*engine_id, &errmsg),
791+ ENGINE_free_fn };
792+ if (e.get () == nullptr ) {
793+ return env->ThrowError (errmsg);
794+ }
795+
796+ if (!ENGINE_init (e.get ())) {
797+ return env->ThrowError (" ENGINE_init" );
798+ }
799+
800+ e.get_deleter () = ENGINE_finish_and_free_fn;
801+
802+ const node::Utf8Value key_name (env->isolate (), args[0 ]);
803+ EVPKeyPointer key (ENGINE_load_private_key (e.get (), *key_name,
804+ nullptr , nullptr ));
805+
806+ if (!key) {
807+ return ThrowCryptoError (env, ERR_get_error (), " ENGINE_load_private_key" );
808+ }
809+
810+ int rv = SSL_CTX_use_PrivateKey (sc->ctx_ .get (), key.get ());
811+
812+ if (rv == 0 ) {
813+ return ThrowCryptoError (env, ERR_get_error (), " SSL_CTX_use_PrivateKey" );
814+ }
815+
816+ sc->private_key_engine_ = std::move (e);
817+ }
818+ #endif // !OPENSSL_NO_ENGINE
819+
767820int SSL_CTX_get_issuer (SSL_CTX* ctx, X509* cert, X509** issuer) {
768821 X509_STORE* store = SSL_CTX_get_cert_store (ctx);
769822 DeleteFnPtr<X509_STORE_CTX, X509_STORE_CTX_free> store_ctx (
@@ -1438,9 +1491,6 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
14381491
14391492
14401493#ifndef OPENSSL_NO_ENGINE
1441- // Helper for the smart pointer.
1442- void ENGINE_free_fn (ENGINE* engine) { ENGINE_free (engine); }
1443-
14441494void SecureContext::SetClientCertEngine (
14451495 const FunctionCallbackInfo<Value>& args) {
14461496 Environment* env = Environment::GetCurrent (args);
0 commit comments