@@ -132,6 +132,8 @@ template int SSLWrap<TLSWrap>::SelectNextProtoCallback(
132132#endif
133133template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void * arg);
134134template void SSLWrap<TLSWrap>::DestroySSL();
135+ template int SSLWrap<TLSWrap>::SSLCertCallback(SSL* s, void * arg);
136+ template void SSLWrap<TLSWrap>::WaitForCertCb(CertCb cb, void * arg);
135137
136138
137139static void crypto_threadid_cb (CRYPTO_THREADID* tid) {
@@ -511,7 +513,8 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
511513 }
512514
513515 while ((ca = PEM_read_bio_X509 (in, nullptr , CryptoPemCallback, nullptr ))) {
514- r = SSL_CTX_add_extra_chain_cert (ctx, ca);
516+ // NOTE: Increments reference count on `ca`
517+ r = SSL_CTX_add1_chain_cert (ctx, ca);
515518
516519 if (!r) {
517520 X509_free (ca);
@@ -987,6 +990,7 @@ void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
987990 env->SetProtoMethod (t, " verifyError" , VerifyError);
988991 env->SetProtoMethod (t, " getCurrentCipher" , GetCurrentCipher);
989992 env->SetProtoMethod (t, " endParser" , EndParser);
993+ env->SetProtoMethod (t, " certCbDone" , CertCbDone);
990994 env->SetProtoMethod (t, " renegotiate" , Renegotiate);
991995 env->SetProtoMethod (t, " shutdownSSL" , Shutdown);
992996 env->SetProtoMethod (t, " getTLSTicket" , GetTLSTicket);
@@ -1869,6 +1873,122 @@ int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
18691873#endif // NODE__HAVE_TLSEXT_STATUS_CB
18701874
18711875
1876+ template <class Base >
1877+ void SSLWrap<Base>::WaitForCertCb(CertCb cb, void * arg) {
1878+ cert_cb_ = cb;
1879+ cert_cb_arg_ = arg;
1880+ }
1881+
1882+
1883+ template <class Base >
1884+ int SSLWrap<Base>::SSLCertCallback(SSL* s, void * arg) {
1885+ Base* w = static_cast <Base*>(SSL_get_app_data (s));
1886+
1887+ if (!w->is_server ())
1888+ return 1 ;
1889+
1890+ if (!w->is_waiting_cert_cb ())
1891+ return 1 ;
1892+
1893+ if (w->cert_cb_running_ )
1894+ return -1 ;
1895+
1896+ Environment* env = w->env ();
1897+ HandleScope handle_scope (env->isolate ());
1898+ Context::Scope context_scope (env->context ());
1899+ w->cert_cb_running_ = true ;
1900+
1901+ Local<Object> info = Object::New (env->isolate ());
1902+
1903+ SSL_SESSION* sess = SSL_get_session (s);
1904+ if (sess != nullptr ) {
1905+ if (sess->tlsext_hostname == nullptr ) {
1906+ info->Set (env->servername_string (), String::Empty (env->isolate ()));
1907+ } else {
1908+ Local<String> servername = OneByteString (env->isolate (),
1909+ sess->tlsext_hostname ,
1910+ strlen (sess->tlsext_hostname ));
1911+ info->Set (env->servername_string (), servername);
1912+ }
1913+ info->Set (env->tls_ticket_string (),
1914+ Boolean::New (env->isolate (), sess->tlsext_ticklen != 0 ));
1915+ }
1916+ bool ocsp = s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp;
1917+ info->Set (env->ocsp_request_string (), Boolean::New (env->isolate (), ocsp));
1918+
1919+ Local<Value> argv[] = { info };
1920+ w->MakeCallback (env->oncertcb_string (), ARRAY_SIZE (argv), argv);
1921+
1922+ if (!w->cert_cb_running_ )
1923+ return 1 ;
1924+
1925+ // Performing async action, wait...
1926+ return -1 ;
1927+ }
1928+
1929+
1930+ template <class Base >
1931+ void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
1932+ Base* w = Unwrap<Base>(args.Holder ());
1933+ Environment* env = w->env ();
1934+
1935+ CHECK (w->is_waiting_cert_cb () && w->cert_cb_running_ );
1936+
1937+ Local<Object> object = w->object ();
1938+ Local<Value> ctx = object->Get (env->sni_context_string ());
1939+ Local<FunctionTemplate> cons = env->secure_context_constructor_template ();
1940+
1941+ // Not an object, probably undefined or null
1942+ if (!ctx->IsObject ())
1943+ goto fire_cb;
1944+
1945+ if (cons->HasInstance (ctx)) {
1946+ SecureContext* sc = Unwrap<SecureContext>(ctx.As <Object>());
1947+ w->sni_context_ .Reset ();
1948+ w->sni_context_ .Reset (env->isolate (), ctx);
1949+
1950+ int rv;
1951+
1952+ // NOTE: reference count is not increased by this API methods
1953+ X509* x509 = SSL_CTX_get0_certificate (sc->ctx_ );
1954+ EVP_PKEY* pkey = SSL_CTX_get0_privatekey (sc->ctx_ );
1955+ STACK_OF (X509)* chain;
1956+
1957+ rv = SSL_CTX_get0_chain_certs (sc->ctx_ , &chain);
1958+ if (rv)
1959+ rv = SSL_use_certificate (w->ssl_ , x509);
1960+ if (rv)
1961+ rv = SSL_use_PrivateKey (w->ssl_ , pkey);
1962+ if (rv && chain != nullptr )
1963+ rv = SSL_set1_chain (w->ssl_ , chain);
1964+ if (!rv) {
1965+ unsigned long err = ERR_get_error ();
1966+ if (!err)
1967+ return env->ThrowError (" CertCbDone" );
1968+ return ThrowCryptoError (env, err);
1969+ }
1970+ } else {
1971+ // Failure: incorrect SNI context object
1972+ Local<Value> err = Exception::TypeError (env->sni_context_err_string ());
1973+ w->MakeCallback (env->onerror_string (), 1 , &err);
1974+ return ;
1975+ }
1976+
1977+ fire_cb:
1978+ CertCb cb;
1979+ void * arg;
1980+
1981+ cb = w->cert_cb_ ;
1982+ arg = w->cert_cb_arg_ ;
1983+
1984+ w->cert_cb_running_ = false ;
1985+ w->cert_cb_ = nullptr ;
1986+ w->cert_cb_arg_ = nullptr ;
1987+
1988+ cb (arg);
1989+ }
1990+
1991+
18721992template <class Base >
18731993void SSLWrap<Base>::SSLGetter(Local<String> property,
18741994 const PropertyCallbackInfo<Value>& info) {
@@ -1975,6 +2095,10 @@ int Connection::HandleSSLError(const char* func,
19752095 DEBUG_PRINT (" [%p] SSL: %s want read\n " , ssl_, func);
19762096 return 0 ;
19772097
2098+ } else if (err == SSL_ERROR_WANT_X509_LOOKUP) {
2099+ DEBUG_PRINT (" [%p] SSL: %s want x509 lookup\n " , ssl_, func);
2100+ return 0 ;
2101+
19782102 } else if (err == SSL_ERROR_ZERO_RETURN) {
19792103 HandleScope scope (ssl_env ()->isolate ());
19802104
@@ -2140,7 +2264,7 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
21402264
21412265 // Call the SNI callback and use its return value as context
21422266 if (!conn->sniObject_ .IsEmpty ()) {
2143- conn->sniContext_ .Reset ();
2267+ conn->sni_context_ .Reset ();
21442268
21452269 Local<Value> arg = PersistentToLocal (env->isolate (), conn->servername_ );
21462270 Local<Value> ret = conn->MakeCallback (env->onselect_string (), 1 , &arg);
@@ -2149,7 +2273,7 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
21492273 Local<FunctionTemplate> secure_context_constructor_template =
21502274 env->secure_context_constructor_template ();
21512275 if (secure_context_constructor_template->HasInstance (ret)) {
2152- conn->sniContext_ .Reset (env->isolate (), ret);
2276+ conn->sni_context_ .Reset (env->isolate (), ret);
21532277 SecureContext* sc = Unwrap<SecureContext>(ret.As <Object>());
21542278 InitNPN (sc);
21552279 SSL_set_SSL_CTX (s, sc->ctx_ );
@@ -2188,6 +2312,8 @@ void Connection::New(const FunctionCallbackInfo<Value>& args) {
21882312
21892313 InitNPN (sc);
21902314
2315+ SSL_set_cert_cb (conn->ssl_ , SSLWrap<Connection>::SSLCertCallback, conn);
2316+
21912317#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
21922318 if (is_server) {
21932319 SSL_CTX_set_tlsext_servername_callback (sc->ctx_ , SelectSNIContextCallback_);
0 commit comments