diff options
Diffstat (limited to 'src/plugins/tls/openssl/qsslcontext_openssl.cpp')
-rw-r--r-- | src/plugins/tls/openssl/qsslcontext_openssl.cpp | 118 |
1 files changed, 53 insertions, 65 deletions
diff --git a/src/plugins/tls/openssl/qsslcontext_openssl.cpp b/src/plugins/tls/openssl/qsslcontext_openssl.cpp index c0afc32e47..75c192bd01 100644 --- a/src/plugins/tls/openssl/qsslcontext_openssl.cpp +++ b/src/plugins/tls/openssl/qsslcontext_openssl.cpp @@ -1,44 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Copyright (C) 2014 BlackBerry Limited. All rights reserved. -** Copyright (C) 2014 Governikus GmbH & Co. KG. -** Copyright (C) 2016 Richard J. Moore <rich@kde.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNetwork module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// Copyright (C) 2014 BlackBerry Limited. All rights reserved. +// Copyright (C) 2014 Governikus GmbH & Co. KG. +// Copyright (C) 2016 Richard J. Moore <rich@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include <QtNetwork/qsslsocket.h> #include <QtNetwork/qssldiffiehellmanparameters.h> @@ -46,6 +10,7 @@ #include "qsslsocket_openssl_symbols_p.h" #include "qsslcontext_openssl_p.h" #include "qtlsbackend_openssl_p.h" +#include "qtlskey_openssl_p.h" #include "qopenssl_p.h" #include <QtNetwork/private/qssl_p.h> @@ -98,17 +63,20 @@ static inline QString msgErrorSettingEllipticCurves(const QString &why) return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why); } -long QSslContext::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions) +qssloptions QSslContext::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions) { - long options; + qssloptions options; switch (protocol) { - case QSsl::SecureProtocols: +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED case QSsl::TlsV1_0OrLater: options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; break; case QSsl::TlsV1_1OrLater: options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1; break; +QT_WARNING_POP + case QSsl::SecureProtocols: case QSsl::TlsV1_2OrLater: options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1; break; @@ -169,21 +137,15 @@ QSslContext::~QSslContext() q_SSL_SESSION_free(session); } -QSslContext* QSslContext::fromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading) -{ - QSslContext *sslContext = new QSslContext(); - initSslContext(sslContext, mode, configuration, allowRootCertOnDemandLoading); - return sslContext; -} - -QSharedPointer<QSslContext> QSslContext::sharedFromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading) +std::shared_ptr<QSslContext> QSslContext::sharedFromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading) { - QSharedPointer<QSslContext> sslContext = QSharedPointer<QSslContext>::create(); - initSslContext(sslContext.data(), mode, configuration, allowRootCertOnDemandLoading); + struct AccessToPrivateCtor : QSslContext {}; + std::shared_ptr<QSslContext> sslContext = std::make_shared<AccessToPrivateCtor>(); + initSslContext(sslContext.get(), mode, configuration, allowRootCertOnDemandLoading); return sslContext; } -QSharedPointer<QSslContext> QSslContext::sharedFromPrivateConfiguration(QSslSocket::SslMode mode, QSslConfigurationPrivate *privConfiguration, +std::shared_ptr<QSslContext> QSslContext::sharedFromPrivateConfiguration(QSslSocket::SslMode mode, QSslConfigurationPrivate *privConfiguration, bool allowRootCertOnDemandLoading) { return sharedFromConfiguration(mode, privConfiguration, allowRootCertOnDemandLoading); @@ -256,7 +218,7 @@ SSL* QSslContext::createSsl() QList<QByteArray> protocols = sslConfiguration.d.constData()->nextAllowedProtocols; if (!protocols.isEmpty()) { m_supportedNPNVersions.clear(); - for (int a = 0; a < protocols.count(); ++a) { + for (int a = 0; a < protocols.size(); ++a) { if (protocols.at(a).size() > 255) { qCWarning(lcTlsBackend) << "TLS NPN extension" << protocols.at(a) << "is too long and will be ignored."; @@ -268,7 +230,7 @@ SSL* QSslContext::createSsl() } if (m_supportedNPNVersions.size()) { m_npnContext.data = reinterpret_cast<unsigned char *>(m_supportedNPNVersions.data()); - m_npnContext.len = m_supportedNPNVersions.count(); + m_npnContext.len = m_supportedNPNVersions.size(); m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone; // Callback's type has a parameter 'const unsigned char ** out' // since it was introduced in 1.0.2. Internally, OpenSSL's own code @@ -363,8 +325,11 @@ void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mo bool isDtls = false; init_context: switch (sslContext->sslConfiguration.protocol()) { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED case QSsl::DtlsV1_0: case QSsl::DtlsV1_0OrLater: +QT_WARNING_POP case QSsl::DtlsV1_2: case QSsl::DtlsV1_2OrLater: #if QT_CONFIG(dtls) @@ -419,6 +384,8 @@ init_context: long maxVersion = anyVersion; switch (sslContext->sslConfiguration.protocol()) { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED case QSsl::TlsV1_0: minVersion = TLS1_VERSION; maxVersion = TLS1_VERSION; @@ -427,6 +394,7 @@ init_context: minVersion = TLS1_1_VERSION; maxVersion = TLS1_1_VERSION; break; +QT_WARNING_POP case QSsl::TlsV1_2: minVersion = TLS1_2_VERSION; maxVersion = TLS1_2_VERSION; @@ -443,7 +411,8 @@ init_context: break; // Ranges: case QSsl::AnyProtocol: - case QSsl::SecureProtocols: +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED case QSsl::TlsV1_0OrLater: minVersion = TLS1_VERSION; maxVersion = 0; @@ -452,25 +421,30 @@ init_context: minVersion = TLS1_1_VERSION; maxVersion = 0; break; +QT_WARNING_POP + case QSsl::SecureProtocols: case QSsl::TlsV1_2OrLater: minVersion = TLS1_2_VERSION; maxVersion = 0; break; +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED case QSsl::DtlsV1_0: minVersion = DTLS1_VERSION; maxVersion = DTLS1_VERSION; break; case QSsl::DtlsV1_0OrLater: minVersion = DTLS1_VERSION; - maxVersion = DTLS_MAX_VERSION; + maxVersion = 0; break; +QT_WARNING_POP case QSsl::DtlsV1_2: minVersion = DTLS1_2_VERSION; maxVersion = DTLS1_2_VERSION; break; case QSsl::DtlsV1_2OrLater: minVersion = DTLS1_2_VERSION; - maxVersion = DTLS_MAX_VERSION; + maxVersion = 0; break; case QSsl::TlsV1_3OrLater: #ifdef TLS1_3_VERSION @@ -502,7 +476,7 @@ init_context: } // Enable bug workarounds. - const long options = setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions); + const qssloptions options = setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions); q_SSL_CTX_set_options(sslContext->ctx, options); // Tell OpenSSL to release memory early @@ -617,6 +591,13 @@ init_context: if (configuration.d->privateKey.algorithm() == QSsl::Opaque) { sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle()); } else { +#ifdef OPENSSL_NO_DEPRECATED_3_0 + auto qtKey = QTlsBackend::backend<QTlsPrivate::TlsKeyOpenSSL>(configuration.d->privateKey); + Q_ASSERT(qtKey); + sslContext->pkey = qtKey->genericKey; + Q_ASSERT(sslContext->pkey); + q_EVP_PKEY_up_ref(sslContext->pkey); +#else // Load private key sslContext->pkey = q_EVP_PKEY_new(); // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free. @@ -629,7 +610,8 @@ init_context: #ifndef OPENSSL_NO_EC else if (configuration.d->privateKey.algorithm() == QSsl::Ec) q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast<EC_KEY *>(configuration.d->privateKey.handle())); -#endif +#endif // OPENSSL_NO_EC +#endif // OPENSSL_NO_DEPRECATED_3_0 } auto pkey = sslContext->pkey; if (configuration.d->privateKey.algorithm() == QSsl::Opaque) @@ -650,7 +632,7 @@ init_context: // If we have any intermediate certificates then we need to add them to our chain bool first = true; - for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) { + for (const QSslCertificate &cert : std::as_const(configuration.d->localCertificateChain)) { if (first) { first = false; continue; @@ -715,15 +697,21 @@ init_context: return; } - if (!dhparams.isEmpty()) { + if (dhparams.isEmpty()) { + q_SSL_CTX_set_dh_auto(sslContext->ctx, 1); + } else { +#ifndef OPENSSL_NO_DEPRECATED_3_0 const QByteArray ¶ms = dhparams.d->derData; const char *ptr = params.constData(); DH *dh = q_d2i_DHparams(nullptr, reinterpret_cast<const unsigned char **>(&ptr), - params.length()); + params.size()); if (dh == nullptr) qFatal("q_d2i_DHparams failed to convert QSslDiffieHellmanParameters to DER form"); q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh); q_DH_free(dh); +#else + qCWarning(lcTlsBackend, "Diffie-Hellman parameters are not supported, because OpenSSL v3 was built with deprecated API removed"); +#endif } #ifndef OPENSSL_NO_PSK |