summaryrefslogtreecommitdiffstats
path: root/src/network/ssl/qsslcontext_opensslpre11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl/qsslcontext_opensslpre11.cpp')
-rw-r--r--src/network/ssl/qsslcontext_opensslpre11.cpp56
1 files changed, 53 insertions, 3 deletions
diff --git a/src/network/ssl/qsslcontext_opensslpre11.cpp b/src/network/ssl/qsslcontext_opensslpre11.cpp
index eea821804f..c8be2ecb31 100644
--- a/src/network/ssl/qsslcontext_opensslpre11.cpp
+++ b/src/network/ssl/qsslcontext_opensslpre11.cpp
@@ -56,11 +56,26 @@ QT_BEGIN_NAMESPACE
extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
extern QString getErrorsFromOpenSsl();
+#if QT_CONFIG(dtls)
+// defined in qdtls_openssl.cpp:
+namespace dtlscallbacks
+{
+extern "C" int q_X509DtlsCallback(int ok, X509_STORE_CTX *ctx);
+extern "C" int q_generate_cookie_callback(SSL *ssl, unsigned char *dst,
+ unsigned *cookieLength);
+extern "C" int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
+ unsigned cookieLength);
+}
+#endif // dtls
+
static inline QString msgErrorSettingEllipticCurves(const QString &why)
{
return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why);
}
+// Defined in qsslsocket.cpp
+QList<QSslCipher> q_getDefaultDtlsCiphers();
+
// static
void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
{
@@ -68,11 +83,28 @@ void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mo
sslContext->errorCode = QSslError::NoError;
bool client = (mode == QSslSocket::SslClientMode);
-
bool reinitialized = false;
bool unsupportedProtocol = false;
+ bool isDtls = false;
init_context:
switch (sslContext->sslConfiguration.protocol()) {
+#if QT_CONFIG(dtls)
+ case QSsl::DtlsV1_0:
+ isDtls = true;
+ sslContext->ctx = q_SSL_CTX_new(client ? q_DTLSv1_client_method() : q_DTLSv1_server_method());
+ break;
+ case QSsl::DtlsV1_2:
+ case QSsl::DtlsV1_2OrLater:
+ // OpenSSL 1.0.2 and below will probably never receive TLS 1.3, so
+ // technically 1.2 or later is 1.2 and will stay so.
+ isDtls = true;
+ sslContext->ctx = q_SSL_CTX_new(client ? q_DTLSv1_2_client_method() : q_DTLSv1_2_server_method());
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ isDtls = true;
+ sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method());
+ break;
+#endif // dtls
case QSsl::SslV2:
#ifndef OPENSSL_NO_SSL2
sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
@@ -138,6 +170,12 @@ init_context:
break;
}
+ if (!client && isDtls && configuration.peerVerifyMode() != QSslSocket::VerifyNone) {
+ sslContext->errorStr = QSslSocket::tr("DTLS server requires a 'VerifyNone' mode with your version of OpenSSL");
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
if (!sslContext->ctx) {
// After stopping Flash 10 the SSL library loses its ciphers. Try re-adding them
// by re-initializing the library.
@@ -155,6 +193,7 @@ init_context:
}
// Enable bug workarounds.
+ // DTLSTODO: check this setupOpenSslOptions ...
long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
q_SSL_CTX_set_options(sslContext->ctx, options);
@@ -170,7 +209,7 @@ init_context:
bool first = true;
QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
if (ciphers.isEmpty())
- ciphers = QSslSocketPrivate::defaultCiphers();
+ ciphers = isDtls ? q_getDefaultDtlsCiphers() : QSslSocketPrivate::defaultCiphers();
for (const QSslCipher &cipher : qAsConst(ciphers)) {
if (first)
first = false;
@@ -277,8 +316,19 @@ init_context:
if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0);
} else {
- q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback);
+ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER,
+#if QT_CONFIG(dtls)
+ isDtls ? dtlscallbacks::q_X509DtlsCallback :
+#endif // dtls
+ q_X509Callback);
+ }
+
+#if QT_CONFIG(dtls)
+ 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, CookieVerifyCallback(dtlscallbacks::q_verify_cookie_callback));
}
+#endif // dtls
// Set verification depth.
if (sslContext->sslConfiguration.peerVerifyDepth() != 0)