@@ -104,7 +104,7 @@ X509_STORE* root_cert_store;
104
104
template class SSLWrap <TLSWrap>;
105
105
template void SSLWrap<TLSWrap>::AddMethods(Environment* env,
106
106
Handle <FunctionTemplate> t);
107
- template void SSLWrap<TLSWrap>::InitNPN(SecureContext* sc);
107
+ template void SSLWrap<TLSWrap>::InitNPN(TLSWrap* w, SecureContext* sc);
108
108
template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
109
109
SSL* s,
110
110
unsigned char * key,
@@ -131,6 +131,8 @@ template int SSLWrap<TLSWrap>::SelectNextProtoCallback(
131
131
void * arg);
132
132
#endif
133
133
template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void * arg);
134
+ template int SSLWrap<TLSWrap>::SSLCertCallback(SSL* s, void * arg);
135
+ template void SSLWrap<TLSWrap>::WaitForCertCb(CertCb cb, void * arg);
134
136
135
137
136
138
static void crypto_threadid_cb (CRYPTO_THREADID* tid) {
@@ -509,7 +511,8 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
509
511
}
510
512
511
513
while ((ca = PEM_read_bio_X509 (in, nullptr , CryptoPemCallback, nullptr ))) {
512
- r = SSL_CTX_add_extra_chain_cert (ctx, ca);
514
+ // NOTE: Increments reference count on `ca`
515
+ r = SSL_CTX_add1_chain_cert (ctx, ca);
513
516
514
517
if (!r) {
515
518
X509_free (ca);
@@ -978,6 +981,7 @@ void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
978
981
env->SetProtoMethod (t, " verifyError" , VerifyError);
979
982
env->SetProtoMethod (t, " getCurrentCipher" , GetCurrentCipher);
980
983
env->SetProtoMethod (t, " endParser" , EndParser);
984
+ env->SetProtoMethod (t, " certCbDone" , CertCbDone);
981
985
env->SetProtoMethod (t, " renegotiate" , Renegotiate);
982
986
env->SetProtoMethod (t, " shutdownSSL" , Shutdown);
983
987
env->SetProtoMethod (t, " getTLSTicket" , GetTLSTicket);
@@ -1008,7 +1012,7 @@ void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
1008
1012
1009
1013
1010
1014
template <class Base >
1011
- void SSLWrap<Base>::InitNPN(SecureContext* sc) {
1015
+ void SSLWrap<Base>::InitNPN(Base* w, SecureContext* sc) {
1012
1016
#ifdef OPENSSL_NPN_NEGOTIATED
1013
1017
// Server should advertise NPN protocols
1014
1018
SSL_CTX_set_next_protos_advertised_cb (sc->ctx_ ,
@@ -1024,6 +1028,8 @@ void SSLWrap<Base>::InitNPN(SecureContext* sc) {
1024
1028
SSL_CTX_set_tlsext_status_cb (sc->ctx_ , TLSExtStatusCallback);
1025
1029
SSL_CTX_set_tlsext_status_arg (sc->ctx_ , nullptr );
1026
1030
#endif // NODE__HAVE_TLSEXT_STATUS_CB
1031
+
1032
+ SSL_set_cert_cb (w->ssl_ , SSLWrap<Base>::SSLCertCallback, w);
1027
1033
}
1028
1034
1029
1035
@@ -1860,6 +1866,122 @@ int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
1860
1866
#endif // NODE__HAVE_TLSEXT_STATUS_CB
1861
1867
1862
1868
1869
+ template <class Base >
1870
+ void SSLWrap<Base>::WaitForCertCb(CertCb cb, void * arg) {
1871
+ cert_cb_ = cb;
1872
+ cert_cb_arg_ = arg;
1873
+ }
1874
+
1875
+
1876
+ template <class Base >
1877
+ int SSLWrap<Base>::SSLCertCallback(SSL* s, void * arg) {
1878
+ Base* w = static_cast <Base*>(SSL_get_app_data (s));
1879
+
1880
+ if (!w->is_server ())
1881
+ return 1 ;
1882
+
1883
+ if (!w->is_waiting_cert_cb ())
1884
+ return 1 ;
1885
+
1886
+ if (w->cert_cb_running_ )
1887
+ return -1 ;
1888
+
1889
+ Environment* env = w->env ();
1890
+ HandleScope handle_scope (env->isolate ());
1891
+ Context::Scope context_scope (env->context ());
1892
+ w->cert_cb_running_ = true ;
1893
+
1894
+ Local<Object> info = Object::New (env->isolate ());
1895
+
1896
+ SSL_SESSION* sess = SSL_get_session (s);
1897
+ if (sess != nullptr ) {
1898
+ if (sess->tlsext_hostname == nullptr ) {
1899
+ info->Set (env->servername_string (), String::Empty (env->isolate ()));
1900
+ } else {
1901
+ Local<String> servername = OneByteString (env->isolate (),
1902
+ sess->tlsext_hostname ,
1903
+ strlen (sess->tlsext_hostname ));
1904
+ info->Set (env->servername_string (), servername);
1905
+ }
1906
+ info->Set (env->tls_ticket_string (),
1907
+ Boolean::New (env->isolate (), sess->tlsext_ticklen != 0 ));
1908
+ }
1909
+ bool ocsp = s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp;
1910
+ info->Set (env->ocsp_request_string (), Boolean::New (env->isolate (), ocsp));
1911
+
1912
+ Local<Value> argv[] = { info };
1913
+ w->MakeCallback (env->oncertcb_string (), ARRAY_SIZE (argv), argv);
1914
+
1915
+ if (!w->cert_cb_running_ )
1916
+ return 1 ;
1917
+
1918
+ // Performing async action, wait...
1919
+ return -1 ;
1920
+ }
1921
+
1922
+
1923
+ template <class Base >
1924
+ void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
1925
+ Base* w = Unwrap<Base>(args.Holder ());
1926
+ Environment* env = w->env ();
1927
+
1928
+ CHECK (w->is_waiting_cert_cb () && w->cert_cb_running_ );
1929
+
1930
+ Local<Object> object = w->object ();
1931
+ Local<Value> ctx = object->Get (env->sni_context_string ());
1932
+ Local<FunctionTemplate> cons = env->secure_context_constructor_template ();
1933
+
1934
+ // Not an object, probably undefined or null
1935
+ if (!ctx->IsObject ())
1936
+ goto fire_cb;
1937
+
1938
+ if (cons->HasInstance (ctx)) {
1939
+ SecureContext* sc = Unwrap<SecureContext>(ctx.As <Object>());
1940
+ w->sni_context_ .Reset ();
1941
+ w->sni_context_ .Reset (env->isolate (), ctx);
1942
+
1943
+ int rv;
1944
+
1945
+ // NOTE: reference count is not increased by this API methods
1946
+ X509* x509 = SSL_CTX_get0_certificate (sc->ctx_ );
1947
+ EVP_PKEY* pkey = SSL_CTX_get0_privatekey (sc->ctx_ );
1948
+ STACK_OF (X509)* chain;
1949
+
1950
+ rv = SSL_CTX_get0_chain_certs (sc->ctx_ , &chain);
1951
+ if (rv)
1952
+ rv = SSL_use_certificate (w->ssl_ , x509);
1953
+ if (rv)
1954
+ rv = SSL_use_PrivateKey (w->ssl_ , pkey);
1955
+ if (rv && chain != nullptr )
1956
+ rv = SSL_set1_chain (w->ssl_ , chain);
1957
+ if (!rv) {
1958
+ unsigned long err = ERR_get_error ();
1959
+ if (!err)
1960
+ return env->ThrowError (" CertCbDone" );
1961
+ return ThrowCryptoError (env, err);
1962
+ }
1963
+ } else {
1964
+ // Failure: incorrect SNI context object
1965
+ Local<Value> err = Exception::TypeError (env->sni_context_err_string ());
1966
+ w->MakeCallback (env->onerror_string (), 1 , &err);
1967
+ return ;
1968
+ }
1969
+
1970
+ fire_cb:
1971
+ CertCb cb;
1972
+ void * arg;
1973
+
1974
+ cb = w->cert_cb_ ;
1975
+ arg = w->cert_cb_arg_ ;
1976
+
1977
+ w->cert_cb_running_ = false ;
1978
+ w->cert_cb_ = nullptr ;
1979
+ w->cert_cb_arg_ = nullptr ;
1980
+
1981
+ cb (arg);
1982
+ }
1983
+
1984
+
1863
1985
template <class Base >
1864
1986
void SSLWrap<Base>::SSLGetter(Local<String> property,
1865
1987
const PropertyCallbackInfo<Value>& info) {
@@ -1955,6 +2077,10 @@ int Connection::HandleSSLError(const char* func,
1955
2077
DEBUG_PRINT (" [%p] SSL: %s want read\n " , ssl_, func);
1956
2078
return 0 ;
1957
2079
2080
+ } else if (err == SSL_ERROR_WANT_X509_LOOKUP) {
2081
+ DEBUG_PRINT (" [%p] SSL: %s want x509 lookup\n " , ssl_, func);
2082
+ return 0 ;
2083
+
1958
2084
} else if (err == SSL_ERROR_ZERO_RETURN) {
1959
2085
HandleScope scope (ssl_env ()->isolate ());
1960
2086
@@ -2120,7 +2246,7 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
2120
2246
2121
2247
// Call the SNI callback and use its return value as context
2122
2248
if (!conn->sniObject_ .IsEmpty ()) {
2123
- conn->sniContext_ .Reset ();
2249
+ conn->sni_context_ .Reset ();
2124
2250
2125
2251
Local<Value> arg = PersistentToLocal (env->isolate (), conn->servername_ );
2126
2252
Local<Value> ret = conn->MakeCallback (env->onselect_string (), 1 , &arg);
@@ -2129,9 +2255,9 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
2129
2255
Local<FunctionTemplate> secure_context_constructor_template =
2130
2256
env->secure_context_constructor_template ();
2131
2257
if (secure_context_constructor_template->HasInstance (ret)) {
2132
- conn->sniContext_ .Reset (env->isolate (), ret);
2258
+ conn->sni_context_ .Reset (env->isolate (), ret);
2133
2259
SecureContext* sc = Unwrap<SecureContext>(ret.As <Object>());
2134
- InitNPN (sc);
2260
+ InitNPN (conn, sc);
2135
2261
SSL_set_SSL_CTX (s, sc->ctx_ );
2136
2262
} else {
2137
2263
return SSL_TLSEXT_ERR_NOACK;
@@ -2166,7 +2292,7 @@ void Connection::New(const FunctionCallbackInfo<Value>& args) {
2166
2292
if (is_server)
2167
2293
SSL_set_info_callback (conn->ssl_ , SSLInfoCallback);
2168
2294
2169
- InitNPN (sc);
2295
+ InitNPN (conn, sc);
2170
2296
2171
2297
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2172
2298
if (is_server) {
0 commit comments