|
21 | 21 |
|
22 | 22 | #include "crypto/crypto_tls.h" |
23 | 23 | #include <cstdio> |
| 24 | +#include <cstring> |
24 | 25 | #include "async_wrap-inl.h" |
25 | 26 | #include "crypto/crypto_bio.h" |
26 | 27 | #include "crypto/crypto_clienthello-inl.h" |
@@ -163,6 +164,29 @@ int NewSessionCallback(SSL* s, SSL_SESSION* sess) { |
163 | 164 | HandleScope handle_scope(env->isolate()); |
164 | 165 | Context::Scope context_scope(env->context()); |
165 | 166 |
|
| 167 | +#ifndef OPENSSL_IS_BORINGSSL |
| 168 | + // OpenSSL does not expose the SNI via SSL_get_servername() on resumed |
| 169 | + // handshakes. Persist the original SNI in the session so it can be restored |
| 170 | + // when the handshake is resumed. |
| 171 | + if (const char* servername = |
| 172 | + SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); |
| 173 | + servername != nullptr) { |
| 174 | + if (SSL_SESSION_set1_hostname(sess, servername) != 1 || |
| 175 | + SSL_SESSION_set1_ticket_appdata(sess, servername, strlen(servername)) != |
| 176 | + 1) { |
| 177 | + return 0; |
| 178 | + } |
| 179 | + |
| 180 | + unsigned int session_id_length = 0; |
| 181 | + const unsigned char* session_id_data = |
| 182 | + SSL_SESSION_get_id(sess, &session_id_length); |
| 183 | + if (SecureContext* sc = w->secure_context(); sc != nullptr) { |
| 184 | + sc->RememberSessionServername( |
| 185 | + session_id_data, session_id_length, servername); |
| 186 | + } |
| 187 | + } |
| 188 | +#endif |
| 189 | + |
166 | 190 | if (!w->has_session_callbacks()) [[unlikely]] |
167 | 191 | return 0; |
168 | 192 |
|
@@ -1367,9 +1391,26 @@ void TLSWrap::GetServername(const FunctionCallbackInfo<Value>& args) { |
1367 | 1391 | auto& sn = servername.value(); |
1368 | 1392 | args.GetReturnValue().Set( |
1369 | 1393 | OneByteString(args.GetIsolate(), sn.data(), sn.length())); |
1370 | | - } else { |
1371 | | - args.GetReturnValue().Set(false); |
| 1394 | + return; |
1372 | 1395 | } |
| 1396 | + |
| 1397 | + SSL_SESSION* sess = SSL_get_session(wrap->ssl_.get()); |
| 1398 | + if (sess != nullptr && wrap->secure_context() != nullptr) { |
| 1399 | + unsigned int session_id_length = 0; |
| 1400 | + const unsigned char* session_id_data = |
| 1401 | + SSL_SESSION_get_id(sess, &session_id_length); |
| 1402 | + |
| 1403 | + auto cached = wrap->secure_context()->GetSessionServername( |
| 1404 | + session_id_data, session_id_length); |
| 1405 | + if (cached.has_value()) { |
| 1406 | + auto& sn = cached.value(); |
| 1407 | + args.GetReturnValue().Set( |
| 1408 | + OneByteString(args.GetIsolate(), sn.data(), sn.length())); |
| 1409 | + return; |
| 1410 | + } |
| 1411 | + } |
| 1412 | + |
| 1413 | + args.GetReturnValue().Set(false); |
1373 | 1414 | } |
1374 | 1415 |
|
1375 | 1416 | void TLSWrap::SetServername(const FunctionCallbackInfo<Value>& args) { |
|
0 commit comments