diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2020-01-27 14:11:08 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2020-01-29 19:38:43 +0100 |
commit | b36b7abb40f04f265c0453a2f4beb466ed462976 (patch) | |
tree | 2353834692f75f65c9dfdace5dbe83f205bfe783 /src/network/ssl/qsslcontext_openssl.cpp | |
parent | 33c9a1e0bcf9c7ced67d5ec62225d6295671d33b (diff) |
Implement/fix session resumption with TLS 1.3
The session we cache at the end of a handshake is non-resumable
in TLS 1.3, since NewSessionTicket message appears quite some time
after the handshake was complete. OpenSSL has a callback where
we can finally obtain a resumable session and inform an application
about session ticket updated by emitting a signal. Truism: OpenSSL-only.
[ChangeLog][QtNetwork] A new signal introduced to report when a valid session ticket received (TLS 1.3)
Fixes: QTBUG-81591
Change-Id: I4d22fad5cc082e431577e20ddbda2835e864b511
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/network/ssl/qsslcontext_openssl.cpp')
-rw-r--r-- | src/network/ssl/qsslcontext_openssl.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 562aa4f518..0aa8a4f438 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -70,6 +70,10 @@ extern "C" int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie, } #endif // dtls +#ifdef TLS1_3_VERSION +extern "C" int q_ssl_sess_set_new_cb(SSL *context, SSL_SESSION *session); +#endif // TLS1_3_VERSION + // Defined in qsslsocket.cpp QList<QSslCipher> q_getDefaultDtlsCiphers(); @@ -168,8 +172,8 @@ SSL* QSslContext::createSsl() if (!session && !sessionASN1().isEmpty() && !sslConfiguration.testSslOption(QSsl::SslOptionDisableSessionPersistence)) { const unsigned char *data = reinterpret_cast<const unsigned char *>(m_sessionASN1.constData()); - session = q_d2i_SSL_SESSION( - nullptr, &data, m_sessionASN1.size()); // refcount is 1 already, set by function above + session = q_d2i_SSL_SESSION(nullptr, &data, m_sessionASN1.size()); + // 'session' has refcount 1 already, set by the function above } if (session) { @@ -585,7 +589,8 @@ init_context: } } - // Initialize peer verification. + // Initialize peer verification, different callbacks, TLS/DTLS verification first + // (note, all these set_some_callback do not have return value): if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) { q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, nullptr); } else { @@ -596,7 +601,17 @@ init_context: q_X509Callback); } +#ifdef TLS1_3_VERSION + // NewSessionTicket callback: + if (mode == QSslSocket::SslClientMode && !isDtls) { + q_SSL_CTX_sess_set_new_cb(sslContext->ctx, q_ssl_sess_set_new_cb); + q_SSL_CTX_set_session_cache_mode(sslContext->ctx, SSL_SESS_CACHE_CLIENT); + } + +#endif // TLS1_3_VERSION + #if QT_CONFIG(dtls) + // DTLS cookies: if (mode == QSslSocket::SslServerMode && isDtls && configuration.dtlsCookieVerificationEnabled()) { q_SSL_CTX_set_cookie_generate_cb(sslContext->ctx, dtlscallbacks::q_generate_cookie_callback); q_SSL_CTX_set_cookie_verify_cb(sslContext->ctx, dtlscallbacks::q_verify_cookie_callback); |