diff options
Diffstat (limited to 'src/network/ssl')
41 files changed, 295 insertions, 184 deletions
diff --git a/src/network/ssl/qasn1element_p.h b/src/network/ssl/qasn1element_p.h index 22948e3ca5..020b5aa1af 100644 --- a/src/network/ssl/qasn1element_p.h +++ b/src/network/ssl/qasn1element_p.h @@ -156,10 +156,10 @@ public: static QAsn1Element fromVector(const QVector<QAsn1Element> &items); static QAsn1Element fromObjectId(const QByteArray &id); - bool toBool(bool *ok = 0) const; + bool toBool(bool *ok = nullptr) const; QDateTime toDateTime() const; QMultiMap<QByteArray, QString> toInfo() const; - qint64 toInteger(bool *ok = 0) const; + qint64 toInteger(bool *ok = nullptr) const; QVector<QAsn1Element> toVector() const; QByteArray toObjectId() const; QByteArray toObjectName() const; diff --git a/src/network/ssl/qdtls.cpp b/src/network/ssl/qdtls.cpp index 3185bfa124..a2280a7d10 100644 --- a/src/network/ssl/qdtls.cpp +++ b/src/network/ssl/qdtls.cpp @@ -342,7 +342,7 @@ QT_BEGIN_NAMESPACE QSslConfiguration QDtlsBasePrivate::configuration() const { auto copyPrivate = new QSslConfigurationPrivate(dtlsConfiguration); - copyPrivate->ref.store(0); // the QSslConfiguration constructor refs up + copyPrivate->ref.storeRelaxed(0); // the QSslConfiguration constructor refs up QSslConfiguration copy(copyPrivate); copyPrivate->sessionCipher = sessionCipher; copyPrivate->sessionProtocol = sessionProtocol; diff --git a/src/network/ssl/qdtls_openssl.cpp b/src/network/ssl/qdtls_openssl.cpp index 8be53df24f..d9ddcceb40 100644 --- a/src/network/ssl/qdtls_openssl.cpp +++ b/src/network/ssl/qdtls_openssl.cpp @@ -729,7 +729,7 @@ bool DtlsState::initCtxAndConnection(QDtlsBasePrivate *dtlsBase) // Create a deep copy of our configuration auto configurationCopy = new QSslConfigurationPrivate(dtlsBase->dtlsConfiguration); - configurationCopy->ref.store(0); // the QSslConfiguration constructor refs up + configurationCopy->ref.storeRelaxed(0); // the QSslConfiguration constructor refs up // DTLSTODO: check we do not set something DTLS-incompatible there ... TlsContext newContext(QSslContext::sharedFromConfiguration(dtlsBase->mode, diff --git a/src/network/ssl/qocspresponse.cpp b/src/network/ssl/qocspresponse.cpp index d564e817ca..bf27bb768b 100644 --- a/src/network/ssl/qocspresponse.cpp +++ b/src/network/ssl/qocspresponse.cpp @@ -133,7 +133,7 @@ QOcspResponse::QOcspResponse(const QOcspResponse &) = default; Move-constructs a QOcspResponse instance. */ -QOcspResponse::QOcspResponse(QOcspResponse &&) Q_DECL_NOTHROW = default; +QOcspResponse::QOcspResponse(QOcspResponse &&) noexcept = default; /*! \since 5.13 @@ -154,7 +154,7 @@ QOcspResponse &QOcspResponse::operator=(const QOcspResponse &) = default; Move-assigns to this QOcspResponse instance. */ -QOcspResponse &QOcspResponse::operator=(QOcspResponse &&) Q_DECL_NOTHROW = default; +QOcspResponse &QOcspResponse::operator=(QOcspResponse &&) noexcept = default; /*! \fn void QOcspResponse::swap(QOcspResponse &other) @@ -239,7 +239,7 @@ Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse & \since 5.13 \relates QHash */ -uint qHash(const QOcspResponse &response, uint seed) +uint qHash(const QOcspResponse &response, uint seed) noexcept { const QOcspResponsePrivate *d = response.d.data(); Q_ASSERT(d); diff --git a/src/network/ssl/qocspresponse.h b/src/network/ssl/qocspresponse.h index 552a088ba5..cf6be5a369 100644 --- a/src/network/ssl/qocspresponse.h +++ b/src/network/ssl/qocspresponse.h @@ -73,7 +73,7 @@ enum class QOcspRevocationReason }; class QOcspResponse; -Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed = 0); +Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed = 0) noexcept; class QOcspResponsePrivate; class Q_NETWORK_EXPORT QOcspResponse @@ -82,11 +82,11 @@ public: QOcspResponse(); QOcspResponse(const QOcspResponse &other); - QOcspResponse(QOcspResponse && other) Q_DECL_NOEXCEPT; + QOcspResponse(QOcspResponse && other) noexcept; ~QOcspResponse(); QOcspResponse &operator = (const QOcspResponse &other); - QOcspResponse &operator = (QOcspResponse &&other) Q_DECL_NOTHROW; + QOcspResponse &operator = (QOcspResponse &&other) noexcept; QOcspCertificateStatus certificateStatus() const; QOcspRevocationReason revocationReason() const; @@ -94,13 +94,13 @@ public: class QSslCertificate responder() const; QSslCertificate subject() const; - void swap(QOcspResponse &other) Q_DECL_NOTHROW { d.swap(other.d); } + void swap(QOcspResponse &other) noexcept { d.swap(other.d); } private: friend class QSslSocketBackendPrivate; friend Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs); - friend Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed); + friend Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed) noexcept; QSharedDataPointer<QOcspResponsePrivate> d; }; diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h index 266fcdacb4..69901b526c 100644 --- a/src/network/ssl/qsslcertificate.h +++ b/src/network/ssl/qsslcertificate.h @@ -66,7 +66,7 @@ class QStringList; class QSslCertificate; // qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) -Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed = 0) Q_DECL_NOTHROW; +Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed = 0) noexcept; class QSslCertificatePrivate; class Q_NETWORK_EXPORT QSslCertificate @@ -88,12 +88,10 @@ public: explicit QSslCertificate(const QByteArray &data = QByteArray(), QSsl::EncodingFormat format = QSsl::Pem); QSslCertificate(const QSslCertificate &other); ~QSslCertificate(); -#ifdef Q_COMPILER_RVALUE_REFS - QSslCertificate &operator=(QSslCertificate &&other) Q_DECL_NOTHROW { swap(other); return *this; } -#endif + QSslCertificate &operator=(QSslCertificate &&other) noexcept { swap(other); return *this; } QSslCertificate &operator=(const QSslCertificate &other); - void swap(QSslCertificate &other) Q_DECL_NOTHROW + void swap(QSslCertificate &other) noexcept { qSwap(d, other.d); } bool operator==(const QSslCertificate &other) const; @@ -169,7 +167,7 @@ private: friend class QSslCertificatePrivate; friend class QSslSocketBackendPrivate; - friend Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW; + friend Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed) noexcept; }; Q_DECLARE_SHARED(QSslCertificate) diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index 899c8a0d2d..6f1fb26add 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -45,12 +45,19 @@ #include "qsslcertificateextension_p.h" #include <QtCore/qendian.h> +#include <QtCore/qmutex.h> -#if QT_CONFIG(thread) -#include <QtCore/private/qmutexpool_p.h> -#endif QT_BEGIN_NAMESPACE +Q_CONSTEXPR int MutexPoolSize = 17; +static QBasicMutex mutexPool[MutexPoolSize]; +namespace QMutexPool { + static QBasicMutex *globalInstanceGet(const void *addr) + { + return mutexPool + (quintptr(addr) % MutexPoolSize); + } +} + // forward declaration static QMultiMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name); @@ -65,7 +72,7 @@ bool QSslCertificate::operator==(const QSslCertificate &other) const return false; } -uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW +uint qHash(const QSslCertificate &key, uint seed) noexcept { if (X509 * const x509 = key.d->x509) { const EVP_MD *sha1 = q_EVP_sha1(); diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h index 4b331d4c4e..234cd45ceb 100644 --- a/src/network/ssl/qsslcertificate_p.h +++ b/src/network/ssl/qsslcertificate_p.h @@ -87,7 +87,7 @@ class QSslCertificatePrivate { public: QSslCertificatePrivate() - : null(true), x509(0) + : null(true), x509(nullptr) { #ifndef QT_NO_SSL QSslSocketPrivate::ensureInitialized(); diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp index cce59b5ef3..8b5035ad96 100644 --- a/src/network/ssl/qsslcertificate_qt.cpp +++ b/src/network/ssl/qsslcertificate_qt.cpp @@ -64,7 +64,7 @@ bool QSslCertificate::operator==(const QSslCertificate &other) const return d->derData == other.d->derData; } -uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW +uint qHash(const QSslCertificate &key, uint seed) noexcept { // DER is the native encoding here, so toDer() is just "return d->derData": return qHash(key.toDer(), seed); diff --git a/src/network/ssl/qsslcertificateextension.h b/src/network/ssl/qsslcertificateextension.h index c2910e1707..7cc8a888be 100644 --- a/src/network/ssl/qsslcertificateextension.h +++ b/src/network/ssl/qsslcertificateextension.h @@ -55,13 +55,11 @@ class Q_NETWORK_EXPORT QSslCertificateExtension public: QSslCertificateExtension(); QSslCertificateExtension(const QSslCertificateExtension &other); -#ifdef Q_COMPILER_RVALUE_REFS - QSslCertificateExtension &operator=(QSslCertificateExtension &&other) Q_DECL_NOTHROW { swap(other); return *this; } -#endif + QSslCertificateExtension &operator=(QSslCertificateExtension &&other) noexcept { swap(other); return *this; } QSslCertificateExtension &operator=(const QSslCertificateExtension &other); ~QSslCertificateExtension(); - void swap(QSslCertificateExtension &other) Q_DECL_NOTHROW { qSwap(d, other.d); } + void swap(QSslCertificateExtension &other) noexcept { qSwap(d, other.d); } QString oid() const; QString name() const; diff --git a/src/network/ssl/qsslcipher.h b/src/network/ssl/qsslcipher.h index c6328e0169..6994f590ae 100644 --- a/src/network/ssl/qsslcipher.h +++ b/src/network/ssl/qsslcipher.h @@ -59,13 +59,11 @@ public: explicit QSslCipher(const QString &name); QSslCipher(const QString &name, QSsl::SslProtocol protocol); QSslCipher(const QSslCipher &other); -#ifdef Q_COMPILER_RVALUE_REFS - QSslCipher &operator=(QSslCipher &&other) Q_DECL_NOTHROW { swap(other); return *this; } -#endif + QSslCipher &operator=(QSslCipher &&other) noexcept { swap(other); return *this; } QSslCipher &operator=(const QSslCipher &other); ~QSslCipher(); - void swap(QSslCipher &other) Q_DECL_NOTHROW + void swap(QSslCipher &other) noexcept { qSwap(d, other.d); } bool operator==(const QSslCipher &other) const; diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h index 8f53e25a53..c25c2686de 100644 --- a/src/network/ssl/qsslconfiguration.h +++ b/src/network/ssl/qsslconfiguration.h @@ -85,12 +85,10 @@ public: QSslConfiguration(); QSslConfiguration(const QSslConfiguration &other); ~QSslConfiguration(); -#ifdef Q_COMPILER_RVALUE_REFS - QSslConfiguration &operator=(QSslConfiguration &&other) Q_DECL_NOTHROW { swap(other); return *this; } -#endif + QSslConfiguration &operator=(QSslConfiguration &&other) noexcept { swap(other); return *this; } QSslConfiguration &operator=(const QSslConfiguration &other); - void swap(QSslConfiguration &other) Q_DECL_NOTHROW + void swap(QSslConfiguration &other) noexcept { qSwap(d, other.d); } bool operator==(const QSslConfiguration &other) const; diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp index 21a5c779f7..db023b7331 100644 --- a/src/network/ssl/qsslcontext_openssl11.cpp +++ b/src/network/ssl/qsslcontext_openssl11.cpp @@ -193,7 +193,6 @@ init_context: minVersion = TLS1_2_VERSION; maxVersion = 0; break; -#if QT_CONFIG(dtls) case QSsl::DtlsV1_0: minVersion = DTLS1_VERSION; maxVersion = DTLS1_VERSION; @@ -210,7 +209,6 @@ init_context: minVersion = DTLS1_2_VERSION; maxVersion = DTLS_MAX_VERSION; break; -#endif // dtls case QSsl::TlsV1_3OrLater: #ifdef TLS1_3_VERSION minVersion = TLS1_3_VERSION; diff --git a/src/network/ssl/qsslcontext_openssl_p.h b/src/network/ssl/qsslcontext_openssl_p.h index 48beebf134..1fa27279c7 100644 --- a/src/network/ssl/qsslcontext_openssl_p.h +++ b/src/network/ssl/qsslcontext_openssl_p.h @@ -89,7 +89,7 @@ public: #if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG) // must be public because we want to use it from an OpenSSL callback struct NPNContext { - NPNContext() : data(0), + NPNContext() : data(nullptr), len(0), status(QSslConfiguration::NextProtocolNegotiationNone) { } diff --git a/src/network/ssl/qssldiffiehellmanparameters.cpp b/src/network/ssl/qssldiffiehellmanparameters.cpp index 65041d4456..7807afaa30 100644 --- a/src/network/ssl/qssldiffiehellmanparameters.cpp +++ b/src/network/ssl/qssldiffiehellmanparameters.cpp @@ -213,7 +213,7 @@ QSslDiffieHellmanParameters &QSslDiffieHellmanParameters::operator=(const QSslDi Setting an empty QSslDiffieHellmanParameters instance on a QSslSocket-based server will disable Diffie-Hellman key exchange. */ -bool QSslDiffieHellmanParameters::isEmpty() const Q_DECL_NOTHROW +bool QSslDiffieHellmanParameters::isEmpty() const noexcept { return d->derData.isNull() && d->error == QSslDiffieHellmanParameters::NoError; } @@ -229,7 +229,7 @@ bool QSslDiffieHellmanParameters::isEmpty() const Q_DECL_NOTHROW \sa error() */ -bool QSslDiffieHellmanParameters::isValid() const Q_DECL_NOTHROW +bool QSslDiffieHellmanParameters::isValid() const noexcept { return d->error == QSslDiffieHellmanParameters::NoError; } @@ -253,7 +253,7 @@ bool QSslDiffieHellmanParameters::isValid() const Q_DECL_NOTHROW Returns the error that caused the QSslDiffieHellmanParameters object to be invalid. */ -QSslDiffieHellmanParameters::Error QSslDiffieHellmanParameters::error() const Q_DECL_NOTHROW +QSslDiffieHellmanParameters::Error QSslDiffieHellmanParameters::error() const noexcept { return d->error; } @@ -262,7 +262,7 @@ QSslDiffieHellmanParameters::Error QSslDiffieHellmanParameters::error() const Q_ Returns a human-readable description of the error that caused the QSslDiffieHellmanParameters object to be invalid. */ -QString QSslDiffieHellmanParameters::errorString() const Q_DECL_NOTHROW +QString QSslDiffieHellmanParameters::errorString() const noexcept { switch (d->error) { case QSslDiffieHellmanParameters::NoError: @@ -283,7 +283,7 @@ QString QSslDiffieHellmanParameters::errorString() const Q_DECL_NOTHROW Returns \c true if \a lhs is equal to \a rhs; otherwise returns \c false. */ -bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) Q_DECL_NOTHROW +bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) noexcept { return lhs.d->derData == rhs.d->derData; } @@ -316,7 +316,7 @@ QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparam) Returns an hash value for \a dhparam, using \a seed to seed the calculation. */ -uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) Q_DECL_NOTHROW +uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) noexcept { return qHash(dhparam.d->derData, seed); } diff --git a/src/network/ssl/qssldiffiehellmanparameters.h b/src/network/ssl/qssldiffiehellmanparameters.h index 497d2bebfb..f62a3b8f44 100644 --- a/src/network/ssl/qssldiffiehellmanparameters.h +++ b/src/network/ssl/qssldiffiehellmanparameters.h @@ -56,16 +56,16 @@ class QSslDiffieHellmanParametersPrivate; class QSslDiffieHellmanParameters; // qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) -Q_NETWORK_EXPORT uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed = 0) Q_DECL_NOTHROW; +Q_NETWORK_EXPORT uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed = 0) noexcept; #ifndef QT_NO_DEBUG_STREAM class QDebug; Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparams); #endif -Q_NETWORK_EXPORT bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) Q_DECL_NOTHROW; +Q_NETWORK_EXPORT bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) noexcept; -inline bool operator!=(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) Q_DECL_NOTHROW +inline bool operator!=(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) noexcept { return !operator==(lhs, rhs); } @@ -83,30 +83,30 @@ public: Q_NETWORK_EXPORT QSslDiffieHellmanParameters(); Q_NETWORK_EXPORT QSslDiffieHellmanParameters(const QSslDiffieHellmanParameters &other); - QSslDiffieHellmanParameters(QSslDiffieHellmanParameters &&other) Q_DECL_NOTHROW : d(other.d) { other.d = nullptr; } + QSslDiffieHellmanParameters(QSslDiffieHellmanParameters &&other) noexcept : d(other.d) { other.d = nullptr; } Q_NETWORK_EXPORT ~QSslDiffieHellmanParameters(); Q_NETWORK_EXPORT QSslDiffieHellmanParameters &operator=(const QSslDiffieHellmanParameters &other); - QSslDiffieHellmanParameters &operator=(QSslDiffieHellmanParameters &&other) Q_DECL_NOTHROW { swap(other); return *this; } + QSslDiffieHellmanParameters &operator=(QSslDiffieHellmanParameters &&other) noexcept { swap(other); return *this; } - void swap(QSslDiffieHellmanParameters &other) Q_DECL_NOTHROW { qSwap(d, other.d); } + void swap(QSslDiffieHellmanParameters &other) noexcept { qSwap(d, other.d); } Q_NETWORK_EXPORT static QSslDiffieHellmanParameters fromEncoded(const QByteArray &encoded, QSsl::EncodingFormat format = QSsl::Pem); Q_NETWORK_EXPORT static QSslDiffieHellmanParameters fromEncoded(QIODevice *device, QSsl::EncodingFormat format = QSsl::Pem); - Q_NETWORK_EXPORT bool isEmpty() const Q_DECL_NOTHROW; - Q_NETWORK_EXPORT bool isValid() const Q_DECL_NOTHROW; - Q_NETWORK_EXPORT Error error() const Q_DECL_NOTHROW; - Q_NETWORK_EXPORT QString errorString() const Q_DECL_NOTHROW; + Q_NETWORK_EXPORT bool isEmpty() const noexcept; + Q_NETWORK_EXPORT bool isValid() const noexcept; + Q_NETWORK_EXPORT Error error() const noexcept; + Q_NETWORK_EXPORT QString errorString() const noexcept; private: QSslDiffieHellmanParametersPrivate *d; friend class QSslContext; - friend Q_NETWORK_EXPORT bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) Q_DECL_NOTHROW; + friend Q_NETWORK_EXPORT bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) noexcept; #ifndef QT_NO_DEBUG_STREAM friend Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparam); #endif - friend Q_NETWORK_EXPORT uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) Q_DECL_NOTHROW; + friend Q_NETWORK_EXPORT uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) noexcept; }; Q_DECLARE_SHARED(QSslDiffieHellmanParameters) diff --git a/src/network/ssl/qsslellipticcurve.h b/src/network/ssl/qsslellipticcurve.h index 57dda19bad..28de3a03b4 100644 --- a/src/network/ssl/qsslellipticcurve.h +++ b/src/network/ssl/qsslellipticcurve.h @@ -52,11 +52,11 @@ QT_BEGIN_NAMESPACE class QSslEllipticCurve; // qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) -Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed = 0) Q_DECL_NOTHROW; +Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed = 0) noexcept; class QSslEllipticCurve { public: - Q_DECL_CONSTEXPR QSslEllipticCurve() Q_DECL_NOTHROW + Q_DECL_CONSTEXPR QSslEllipticCurve() noexcept : id(0) { } @@ -67,18 +67,18 @@ public: Q_REQUIRED_RESULT Q_NETWORK_EXPORT QString shortName() const; Q_REQUIRED_RESULT Q_NETWORK_EXPORT QString longName() const; - Q_DECL_CONSTEXPR bool isValid() const Q_DECL_NOTHROW + Q_DECL_CONSTEXPR bool isValid() const noexcept { return id != 0; } - Q_NETWORK_EXPORT bool isTlsNamedCurve() const Q_DECL_NOTHROW; + Q_NETWORK_EXPORT bool isTlsNamedCurve() const noexcept; private: int id; - friend Q_DECL_CONSTEXPR bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) Q_DECL_NOTHROW; - friend Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed) Q_DECL_NOTHROW; + friend Q_DECL_CONSTEXPR bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) noexcept; + friend Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed) noexcept; friend class QSslContext; friend class QSslSocketPrivate; @@ -87,13 +87,13 @@ private: Q_DECLARE_TYPEINFO(QSslEllipticCurve, Q_PRIMITIVE_TYPE); -Q_DECL_CONSTEXPR inline uint qHash(QSslEllipticCurve curve, uint seed) Q_DECL_NOTHROW +Q_DECL_CONSTEXPR inline uint qHash(QSslEllipticCurve curve, uint seed) noexcept { return qHash(curve.id, seed); } -Q_DECL_CONSTEXPR inline bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) Q_DECL_NOTHROW +Q_DECL_CONSTEXPR inline bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) noexcept { return lhs.id == rhs.id; } -Q_DECL_CONSTEXPR inline bool operator!=(QSslEllipticCurve lhs, QSslEllipticCurve rhs) Q_DECL_NOTHROW +Q_DECL_CONSTEXPR inline bool operator!=(QSslEllipticCurve lhs, QSslEllipticCurve rhs) noexcept { return !operator==(lhs, rhs); } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/network/ssl/qsslellipticcurve_dummy.cpp b/src/network/ssl/qsslellipticcurve_dummy.cpp index 93e081b9e0..1313e06875 100644 --- a/src/network/ssl/qsslellipticcurve_dummy.cpp +++ b/src/network/ssl/qsslellipticcurve_dummy.cpp @@ -63,7 +63,7 @@ QSslEllipticCurve QSslEllipticCurve::fromLongName(const QString &name) return QSslEllipticCurve(); } -bool QSslEllipticCurve::isTlsNamedCurve() const Q_DECL_NOTHROW +bool QSslEllipticCurve::isTlsNamedCurve() const noexcept { return false; } diff --git a/src/network/ssl/qsslellipticcurve_openssl.cpp b/src/network/ssl/qsslellipticcurve_openssl.cpp index 8cd14837f0..b5e38ada53 100644 --- a/src/network/ssl/qsslellipticcurve_openssl.cpp +++ b/src/network/ssl/qsslellipticcurve_openssl.cpp @@ -170,7 +170,7 @@ static const int tlsNamedCurveNIDs[] = { static const size_t tlsNamedCurveNIDCount = sizeof(tlsNamedCurveNIDs) / sizeof(tlsNamedCurveNIDs[0]); -bool QSslEllipticCurve::isTlsNamedCurve() const Q_DECL_NOTHROW +bool QSslEllipticCurve::isTlsNamedCurve() const noexcept { const int * const tlsNamedCurveNIDsEnd = tlsNamedCurveNIDs + tlsNamedCurveNIDCount; return std::find(tlsNamedCurveNIDs, tlsNamedCurveNIDsEnd, id) != tlsNamedCurveNIDsEnd; diff --git a/src/network/ssl/qsslerror.cpp b/src/network/ssl/qsslerror.cpp index 02dd16a58d..cdc018a508 100644 --- a/src/network/ssl/qsslerror.cpp +++ b/src/network/ssl/qsslerror.cpp @@ -86,6 +86,7 @@ \value UnspecifiedError \value NoSslSupport \value CertificateBlacklisted + \value CertificateStatusUnknown \value OcspNoResponseFound \value OcspMalformedRequest \value OcspMalformedResponse @@ -361,11 +362,11 @@ QSslCertificate QSslError::certificate() const \since 5.4 \relates QHash */ -uint qHash(const QSslError &key, uint seed) Q_DECL_NOTHROW +uint qHash(const QSslError &key, uint seed) noexcept { - // 2x boost::hash_combine inlined: - seed ^= qHash(key.error()) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - seed ^= qHash(key.certificate()) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + QtPrivate::QHashCombine hash; + seed = hash(seed, key.error()); + seed = hash(seed, key.certificate()); return seed; } diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h index 513b8afd7f..28eb1a9ea8 100644 --- a/src/network/ssl/qsslerror.h +++ b/src/network/ssl/qsslerror.h @@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE class QSslErrorPrivate; class Q_NETWORK_EXPORT QSslError { + Q_GADGET public: enum SslError { NoError, @@ -94,6 +95,7 @@ public: OcspStatusUnknown, UnspecifiedError = -1 }; + Q_ENUM(SslError) // RVCT compiler in debug build does not like about default values in const- // So as an workaround we define all constructor overloads here explicitly @@ -103,13 +105,11 @@ public: QSslError(const QSslError &other); - void swap(QSslError &other) Q_DECL_NOTHROW + void swap(QSslError &other) noexcept { qSwap(d, other.d); } ~QSslError(); -#ifdef Q_COMPILER_RVALUE_REFS - QSslError &operator=(QSslError &&other) Q_DECL_NOTHROW { swap(other); return *this; } -#endif + QSslError &operator=(QSslError &&other) noexcept { swap(other); return *this; } QSslError &operator=(const QSslError &other); bool operator==(const QSslError &other) const; inline bool operator!=(const QSslError &other) const @@ -124,7 +124,7 @@ private: }; Q_DECLARE_SHARED(QSslError) -Q_NETWORK_EXPORT uint qHash(const QSslError &key, uint seed = 0) Q_DECL_NOTHROW; +Q_NETWORK_EXPORT uint qHash(const QSslError &key, uint seed = 0) noexcept; #ifndef QT_NO_DEBUG_STREAM class QDebug; diff --git a/src/network/ssl/qsslkey.h b/src/network/ssl/qsslkey.h index 6de02b1e44..74be406539 100644 --- a/src/network/ssl/qsslkey.h +++ b/src/network/ssl/qsslkey.h @@ -71,13 +71,12 @@ public: const QByteArray &passPhrase = QByteArray()); explicit QSslKey(Qt::HANDLE handle, QSsl::KeyType type = QSsl::PrivateKey); QSslKey(const QSslKey &other); -#ifdef Q_COMPILER_RVALUE_REFS - QSslKey &operator=(QSslKey &&other) Q_DECL_NOTHROW { swap(other); return *this; } -#endif + QSslKey(QSslKey &&other) noexcept; + QSslKey &operator=(QSslKey &&other) noexcept; QSslKey &operator=(const QSslKey &other); ~QSslKey(); - void swap(QSslKey &other) Q_DECL_NOTHROW { qSwap(d, other.d); } + void swap(QSslKey &other) noexcept { qSwap(d, other.d); } bool isNull() const; void clear(); diff --git a/src/network/ssl/qsslkey_mac.cpp b/src/network/ssl/qsslkey_mac.cpp index d460cbfdab..814fe1c4bc 100644 --- a/src/network/ssl/qsslkey_mac.cpp +++ b/src/network/ssl/qsslkey_mac.cpp @@ -42,7 +42,9 @@ #include <CommonCrypto/CommonCrypto.h> -QT_USE_NAMESPACE +#include <cstddef> + +QT_BEGIN_NAMESPACE static QByteArray wrapCCCrypt(CCOperation ccOp, QSslKeyPrivate::Cipher cipher, @@ -64,17 +66,23 @@ static QByteArray wrapCCCrypt(CCOperation ccOp, blockSize = kCCBlockSizeRC2; ccAlgorithm = kCCAlgorithmRC2; break; - }; + case QSslKeyPrivate::Aes128Cbc: + case QSslKeyPrivate::Aes192Cbc: + case QSslKeyPrivate::Aes256Cbc: + blockSize = kCCBlockSizeAES128; + ccAlgorithm = kCCAlgorithmAES; + break; + } size_t plainLength = 0; QByteArray plain(data.size() + blockSize, 0); CCCryptorStatus status = CCCrypt( ccOp, ccAlgorithm, kCCOptionPKCS7Padding, - key.constData(), key.size(), + key.constData(), std::size_t(key.size()), iv.constData(), - data.constData(), data.size(), - plain.data(), plain.size(), &plainLength); + data.constData(), std::size_t(data.size()), + plain.data(), std::size_t(plain.size()), &plainLength); if (status == kCCSuccess) - return plain.left(plainLength); + return plain.left(int(plainLength)); return QByteArray(); } @@ -87,3 +95,5 @@ QByteArray QSslKeyPrivate::encrypt(Cipher cipher, const QByteArray &data, const { return wrapCCCrypt(kCCEncrypt, cipher, data, key, iv); } + +QT_END_NAMESPACE diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp index 99c1a39c73..888058df22 100644 --- a/src/network/ssl/qsslkey_openssl.cpp +++ b/src/network/ssl/qsslkey_openssl.cpp @@ -333,6 +333,15 @@ static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data, type = q_EVP_rc2_cbc(); #endif break; + case QSslKeyPrivate::Aes128Cbc: + type = q_EVP_aes_128_cbc(); + break; + case QSslKeyPrivate::Aes192Cbc: + type = q_EVP_aes_192_cbc(); + break; + case QSslKeyPrivate::Aes256Cbc: + type = q_EVP_aes_256_cbc(); + break; } if (type == nullptr) diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp index 5c90719fcd..b0d6c729f9 100644 --- a/src/network/ssl/qsslkey_p.cpp +++ b/src/network/ssl/qsslkey_p.cpp @@ -385,6 +385,24 @@ QSslKey::QSslKey(const QSslKey &other) : d(other.d) { } +QSslKey::QSslKey(QSslKey &&other) noexcept + : d(nullptr) +{ + qSwap(d, other.d); +} + +QSslKey &QSslKey::operator=(QSslKey &&other) noexcept +{ + if (this == &other) + return *this; + + // If no one else is referencing the key data we want to make sure + // before we swap the d-ptr that it is not left in memory. + d.reset(); + qSwap(d, other.d); + return *this; +} + /*! Destroys the QSslKey object. */ diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h index 06403b5479..dd1a31b0e5 100644 --- a/src/network/ssl/qsslkey_p.h +++ b/src/network/ssl/qsslkey_p.h @@ -68,7 +68,7 @@ class QSslKeyPrivate public: inline QSslKeyPrivate() : algorithm(QSsl::Opaque) - , opaque(0) + , opaque(nullptr) { clear(false); } @@ -105,7 +105,10 @@ public: enum Cipher { DesCbc, DesEde3Cbc, - Rc2Cbc + Rc2Cbc, + Aes128Cbc, + Aes192Cbc, + Aes256Cbc }; Q_AUTOTEST_EXPORT static QByteArray decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv); diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp index 5ebd8ac3bd..43969c3d28 100644 --- a/src/network/ssl/qsslkey_qt.cpp +++ b/src/network/ssl/qsslkey_qt.cpp @@ -48,6 +48,8 @@ #include <QtNetwork/qpassworddigestor.h> +#include <cstring> + QT_USE_NAMESPACE static const quint8 bits_table[256] = { @@ -124,6 +126,37 @@ static int numberOfBits(const QByteArray &modulus) return bits; } +static QByteArray deriveAesKey(QSslKeyPrivate::Cipher cipher, const QByteArray &passPhrase, const QByteArray &iv) +{ + // This is somewhat simplified and shortened version of what OpenSSL does. + // See, for example, EVP_BytesToKey for the "algorithm" itself and elsewhere + // in their code for what they pass as arguments to EVP_BytesToKey when + // deriving encryption keys (when reading/writing pems files with encrypted + // keys). + + Q_ASSERT(iv.size() >= 8); + + QCryptographicHash hash(QCryptographicHash::Md5); + + QByteArray data(passPhrase); + data.append(iv.data(), 8); // AKA PKCS5_SALT_LEN in OpenSSL. + + hash.addData(data); + + if (cipher == QSslKeyPrivate::Aes128Cbc) + return hash.result(); + + QByteArray key(hash.result()); + hash.reset(); + hash.addData(key); + hash.addData(data); + + if (cipher == QSslKeyPrivate::Aes192Cbc) + return key.append(hash.result().constData(), 8); + + return key.append(hash.result()); +} + static QByteArray deriveKey(QSslKeyPrivate::Cipher cipher, const QByteArray &passPhrase, const QByteArray &iv) { QByteArray key; @@ -145,14 +178,19 @@ static QByteArray deriveKey(QSslKeyPrivate::Cipher cipher, const QByteArray &pas case QSslKeyPrivate::Rc2Cbc: key = hash.result(); break; + case QSslKeyPrivate::Aes128Cbc: + case QSslKeyPrivate::Aes192Cbc: + case QSslKeyPrivate::Aes256Cbc: + return deriveAesKey(cipher, passPhrase, iv); } return key; } void QSslKeyPrivate::clear(bool deep) { - Q_UNUSED(deep); isNull = true; + if (deep) + std::memset(derData.data(), 0, derData.size()); derData.clear(); keyLength = -1; } @@ -378,6 +416,12 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra cipher = DesEde3Cbc; } else if (dekInfo.first() == "RC2-CBC") { cipher = Rc2Cbc; + } else if (dekInfo.first() == "AES-128-CBC") { + cipher = Aes128Cbc; + } else if (dekInfo.first() == "AES-192-CBC") { + cipher = Aes192Cbc; + } else if (dekInfo.first() == "AES-256-CBC") { + cipher = Aes256Cbc; } else { clear(deepClear); return; @@ -554,6 +598,10 @@ static EncryptionData readPbes2(const QVector<QAsn1Element> &element, const QByt return {}; break; } // @todo(?): case (RC5 , AES) + case QSslKeyPrivate::Cipher::Aes128Cbc: + case QSslKeyPrivate::Cipher::Aes192Cbc: + case QSslKeyPrivate::Cipher::Aes256Cbc: + Q_UNREACHABLE(); } if (Q_LIKELY(keyDerivationAlgorithm == PKCS5_PBKDF2_ENCRYPTION_OID)) { diff --git a/src/network/ssl/qsslkey_schannel.cpp b/src/network/ssl/qsslkey_schannel.cpp index 5694068860..1e21d123f4 100644 --- a/src/network/ssl/qsslkey_schannel.cpp +++ b/src/network/ssl/qsslkey_schannel.cpp @@ -57,6 +57,10 @@ const wchar_t *getName(QSslKeyPrivate::Cipher cipher) return BCRYPT_3DES_ALGORITHM; case QSslKeyPrivate::Cipher::Rc2Cbc: return BCRYPT_RC2_ALGORITHM; + case QSslKeyPrivate::Cipher::Aes128Cbc: + case QSslKeyPrivate::Cipher::Aes192Cbc: + case QSslKeyPrivate::Cipher::Aes256Cbc: + return BCRYPT_AES_ALGORITHM; } Q_UNREACHABLE(); } diff --git a/src/network/ssl/qsslkey_winrt.cpp b/src/network/ssl/qsslkey_winrt.cpp index f2ed813965..69eaaa387f 100644 --- a/src/network/ssl/qsslkey_winrt.cpp +++ b/src/network/ssl/qsslkey_winrt.cpp @@ -83,6 +83,15 @@ struct SslKeyGlobal hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"RC2_CBC").Get(), &keyProviders[QSslKeyPrivate::Rc2Cbc]); Q_ASSERT_SUCCEEDED(hr); + hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"AES_CBC").Get(), + &keyProviders[QSslKeyPrivate::Aes128Cbc]); + Q_ASSERT_SUCCEEDED(hr); + hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"AES_CBC").Get(), + &keyProviders[QSslKeyPrivate::Aes192Cbc]); + Q_ASSERT_SUCCEEDED(hr); + hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"AES_CBC").Get(), + &keyProviders[QSslKeyPrivate::Aes256Cbc]); + Q_ASSERT_SUCCEEDED(hr); hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_CryptographicBuffer).Get(), &bufferFactory); diff --git a/src/network/ssl/qsslpresharedkeyauthenticator.h b/src/network/ssl/qsslpresharedkeyauthenticator.h index 423f7731b4..5d714dc34e 100644 --- a/src/network/ssl/qsslpresharedkeyauthenticator.h +++ b/src/network/ssl/qsslpresharedkeyauthenticator.h @@ -59,11 +59,9 @@ public: Q_NETWORK_EXPORT QSslPreSharedKeyAuthenticator(const QSslPreSharedKeyAuthenticator &authenticator); Q_NETWORK_EXPORT QSslPreSharedKeyAuthenticator &operator=(const QSslPreSharedKeyAuthenticator &authenticator); -#ifdef Q_COMPILER_RVALUE_REFS - QSslPreSharedKeyAuthenticator &operator=(QSslPreSharedKeyAuthenticator &&other) Q_DECL_NOTHROW { swap(other); return *this; } -#endif + QSslPreSharedKeyAuthenticator &operator=(QSslPreSharedKeyAuthenticator &&other) noexcept { swap(other); return *this; } - void swap(QSslPreSharedKeyAuthenticator &other) Q_DECL_NOTHROW { qSwap(d, other.d); } + void swap(QSslPreSharedKeyAuthenticator &other) noexcept { qSwap(d, other.d); } Q_NETWORK_EXPORT QByteArray identityHint() const; diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index e164217e4e..e302aa1761 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -761,8 +761,8 @@ qint64 QSslSocket::bytesAvailable() const { Q_D(const QSslSocket); if (d->mode == UnencryptedMode) - return QIODevice::bytesAvailable() + (d->plainSocket ? d->plainSocket->bytesAvailable() : 0); - return QIODevice::bytesAvailable(); + return QAbstractSocket::bytesAvailable() + (d->plainSocket ? d->plainSocket->bytesAvailable() : 0); + return QAbstractSocket::bytesAvailable(); } /*! @@ -818,8 +818,8 @@ bool QSslSocket::canReadLine() const { Q_D(const QSslSocket); if (d->mode == UnencryptedMode) - return QIODevice::canReadLine() || (d->plainSocket && d->plainSocket->canReadLine()); - return QIODevice::canReadLine(); + return QAbstractSocket::canReadLine() || (d->plainSocket && d->plainSocket->canReadLine()); + return QAbstractSocket::canReadLine(); } /*! @@ -849,8 +849,8 @@ bool QSslSocket::atEnd() const { Q_D(const QSslSocket); if (d->mode == UnencryptedMode) - return QIODevice::atEnd() && (!d->plainSocket || d->plainSocket->atEnd()); - return QIODevice::atEnd(); + return QAbstractSocket::atEnd() && (!d->plainSocket || d->plainSocket->atEnd()); + return QAbstractSocket::atEnd(); } /*! @@ -924,7 +924,7 @@ QSslConfiguration QSslSocket::sslConfiguration() const // create a deep copy of our configuration QSslConfigurationPrivate *copy = new QSslConfigurationPrivate(d->configuration); - copy->ref.store(0); // the QSslConfiguration constructor refs up + copy->ref.storeRelaxed(0); // the QSslConfiguration constructor refs up copy->sessionCipher = d->sessionCipher(); copy->sessionProtocol = d->sessionProtocol(); @@ -1209,12 +1209,21 @@ void QSslSocket::setPrivateKey(const QSslKey &key) void QSslSocket::setPrivateKey(const QString &fileName, QSsl::KeyAlgorithm algorithm, QSsl::EncodingFormat format, const QByteArray &passPhrase) { - Q_D(QSslSocket); QFile file(fileName); - if (file.open(QIODevice::ReadOnly)) { - d->configuration.privateKey = QSslKey(file.readAll(), algorithm, - format, QSsl::PrivateKey, passPhrase); + if (!file.open(QIODevice::ReadOnly)) { + qCWarning(lcSsl, "QSslSocket::setPrivateKey: Couldn't open file for reading"); + return; + } + + QSslKey key(file.readAll(), algorithm, format, QSsl::PrivateKey, passPhrase); + if (key.isNull()) { + qCWarning(lcSsl, "QSslSocket::setPrivateKey: " + "The specified file does not contain a valid key"); + return; } + + Q_D(QSslSocket); + d->configuration.privateKey = key; } /*! @@ -1503,7 +1512,7 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor SSL socket's CA certificate database is initialized to the default CA certificate database. - \sa QSslConfiguration::defaultCaCertificates(), addCaCertificates() + \sa QSslConfiguration::caCertificates(), addCaCertificates() */ void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate) { @@ -2369,7 +2378,7 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri if (!global) return; - ptr->ref.store(1); + ptr->ref.storeRelaxed(1); ptr->peerCertificate = global->peerCertificate; ptr->peerCertificateChain = global->peerCertificateChain; ptr->localCertificateChain = global->localCertificateChain; diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index e290ba79dd..e0e065679d 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -215,7 +215,7 @@ void QSecureTransportContext::reset(SSLContextRef newContext) context = newContext; } -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_securetransport_mutex, (QMutex::Recursive)) +Q_GLOBAL_STATIC(QRecursiveMutex, qt_securetransport_mutex) //#define QSSLSOCKET_DEBUG diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index c0035d23a8..d4bad1b1a5 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -523,11 +523,12 @@ bool QSslSocketBackendPrivate::initSslContext() { Q_Q(QSslSocket); - // If no external context was set (e.g. bei QHttpNetworkConnection) we will create a default context + // If no external context was set (e.g. by QHttpNetworkConnection) we will + // create a default context if (!sslContextPointer) { // create a deep copy of our configuration QSslConfigurationPrivate *configurationCopy = new QSslConfigurationPrivate(configuration); - configurationCopy->ref.store(0); // the QSslConfiguration constructor refs up + configurationCopy->ref.storeRelaxed(0); // the QSslConfiguration constructor refs up sslContextPointer = QSslContext::sharedFromConfiguration(mode, configurationCopy, allowRootCertOnDemandLoading); } diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp index b60b8be41f..1d935c5217 100644 --- a/src/network/ssl/qsslsocket_openssl11.cpp +++ b/src/network/ssl/qsslsocket_openssl11.cpp @@ -68,10 +68,11 @@ #include <QtCore/qfile.h> #include <QtCore/qmutex.h> #include <QtCore/qlibrary.h> +#include <QtCore/qoperatingsystemversion.h> QT_BEGIN_NAMESPACE -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_opensslInitMutex, (QMutex::Recursive)) +Q_GLOBAL_STATIC(QRecursiveMutex, qt_opensslInitMutex) void QSslSocketPrivate::deinitialize() { @@ -142,13 +143,12 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded() if (!s_loadRootCertsOnDemand) setDefaultCaCertificates(systemCaCertificates()); #ifdef Q_OS_WIN - //Enabled for fetching additional root certs from windows update on windows 6+ + //Enabled for fetching additional root certs from windows update on windows. //This flag is set false by setDefaultCaCertificates() indicating the app uses //its own cert bundle rather than the system one. //Same logic that disables the unix on demand cert loading. //Unlike unix, we do preload the certificates from the cert store. - if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_6_0) - s_loadRootCertsOnDemand = true; + s_loadRootCertsOnDemand = true; #endif } diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h index 150617e3d2..0fe0899d4f 100644 --- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h @@ -82,6 +82,7 @@ Q_AUTOTEST_EXPORT const BIO_METHOD *q_BIO_s_mem(); int q_DSA_bits(DSA *a); int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c); +Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a); int q_EVP_PKEY_base_id(EVP_PKEY *a); int q_RSA_bits(RSA *a); Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a); diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 74ac852bcd..1fcfdf9f16 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -63,13 +63,11 @@ # include <QtCore/qlibrary.h> #endif #include <QtCore/qmutex.h> -#if QT_CONFIG(thread) -#include <private/qmutexpool_p.h> -#endif #include <QtCore/qdatetime.h> #if defined(Q_OS_UNIX) #include <QtCore/qdir.h> #endif +#include <QtCore/private/qmemory_p.h> #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) #include <link.h> #endif @@ -150,6 +148,7 @@ DEFINEFUNC(BIO *, BIO_new, const BIO_METHOD *a, a, return nullptr, return) DEFINEFUNC(const BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return nullptr, return) DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return) DEFINEFUNC(int, EVP_CIPHER_CTX_reset, EVP_CIPHER_CTX *c, c, return 0, return) +DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return) DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return) DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return) DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return) @@ -363,6 +362,11 @@ DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return null #ifndef OPENSSL_NO_RC2 DEFINEFUNC(const EVP_CIPHER *, EVP_rc2_cbc, DUMMYARG, DUMMYARG, return nullptr, return) #endif +#ifndef OPENSSL_NO_AES +DEFINEFUNC(const EVP_CIPHER *, EVP_aes_128_cbc, DUMMYARG, DUMMYARG, return nullptr, return) +DEFINEFUNC(const EVP_CIPHER *, EVP_aes_192_cbc, DUMMYARG, DUMMYARG, return nullptr, return) +DEFINEFUNC(const EVP_CIPHER *, EVP_aes_256_cbc, DUMMYARG, DUMMYARG, return nullptr, return) +#endif DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return) DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return) @@ -371,6 +375,7 @@ DEFINEFUNC2(int, EVP_PKEY_set1_DH, EVP_PKEY *a, a, DH *b, b, return -1, return) #ifndef OPENSSL_NO_EC DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return) #endif +DEFINEFUNC2(int, EVP_PKEY_cmp, const EVP_PKEY *a, a, const EVP_PKEY *b, b, return -1, return) DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG) DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return) DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return) @@ -592,8 +597,8 @@ DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, re DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG) #define RESOLVEFUNC(func) \ - if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \ - && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \ + if (!(_q_##func = _q_PTR_##func(libs.ssl->resolve(#func))) \ + && !(_q_##func = _q_PTR_##func(libs.crypto->resolve(#func)))) \ qsslSocketCannotResolveSymbolWarning(#func); #if !defined QT_LINKED_OPENSSL @@ -692,7 +697,7 @@ static QStringList libraryPathList() // discover paths of already loaded libraries QSet<QString> loadedPaths; dl_iterate_phdr(dlIterateCallback, &loadedPaths); - paths.append(loadedPaths.toList()); + paths.append(loadedPaths.values()); #endif return paths; @@ -729,34 +734,31 @@ static QStringList findAllLibCrypto() # endif #ifdef Q_OS_WIN -static bool tryToLoadOpenSslWin32Library(QLatin1String ssleay32LibName, QLatin1String libeay32LibName, QPair<QSystemLibrary*, QSystemLibrary*> &pair) -{ - pair.first = 0; - pair.second = 0; - QSystemLibrary *ssleay32 = new QSystemLibrary(ssleay32LibName); +struct LoadedOpenSsl { + std::unique_ptr<QSystemLibrary> ssl, crypto; +}; + +static bool tryToLoadOpenSslWin32Library(QLatin1String ssleay32LibName, QLatin1String libeay32LibName, LoadedOpenSsl &result) +{ + auto ssleay32 = qt_make_unique<QSystemLibrary>(ssleay32LibName); if (!ssleay32->load(false)) { - delete ssleay32; return FALSE; } - QSystemLibrary *libeay32 = new QSystemLibrary(libeay32LibName); + auto libeay32 = qt_make_unique<QSystemLibrary>(libeay32LibName); if (!libeay32->load(false)) { - delete ssleay32; - delete libeay32; return FALSE; } - pair.first = ssleay32; - pair.second = libeay32; + result.ssl = std::move(ssleay32); + result.crypto = std::move(libeay32); return TRUE; } -static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32() +static LoadedOpenSsl loadOpenSsl() { - QPair<QSystemLibrary*,QSystemLibrary*> pair; - pair.first = 0; - pair.second = 0; + LoadedOpenSsl result; #if QT_CONFIG(opensslv11) // With OpenSSL 1.1 the names have changed to libssl-1_1(-x64) and libcrypto-1_1(-x64), for builds using @@ -769,7 +771,7 @@ static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32() #endif // !Q_PROCESSOR_x86_64 tryToLoadOpenSslWin32Library(QLatin1String("libssl-1_1" QT_SSL_SUFFIX), - QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), pair); + QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), result); #undef QT_SSL_SUFFIX @@ -778,28 +780,30 @@ static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32() // When OpenSSL is built using MSVC then the libraries are named 'ssleay32.dll' and 'libeay32'dll'. // When OpenSSL is built using GCC then different library names are used (depending on the OpenSSL version) // The oldest version of a GCC-based OpenSSL which can be detected by the code below is 0.9.8g (released in 2007) - if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), pair)) { - if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), pair)) { - if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), pair)) { - tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), pair); + if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), result)) { + if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), result)) { + if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), result)) { + tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), result); } } } #endif // !QT_CONFIG(opensslv11) - return pair; + return result; } #else -static QPair<QLibrary*, QLibrary*> loadOpenSsl() +struct LoadedOpenSsl { + std::unique_ptr<QLibrary> ssl, crypto; +}; + +static LoadedOpenSsl loadOpenSsl() { - QPair<QLibrary*,QLibrary*> pair; + LoadedOpenSsl result = {qt_make_unique<QLibrary>(), qt_make_unique<QLibrary>()}; # if defined(Q_OS_UNIX) - QLibrary *&libssl = pair.first; - QLibrary *&libcrypto = pair.second; - libssl = new QLibrary; - libcrypto = new QLibrary; + QLibrary * const libssl = result.ssl.get(); + QLibrary * const libcrypto = result.crypto.get(); // Try to find the libssl library on the system. // @@ -843,7 +847,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl() libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER)); if (libcrypto->load() && libssl->load()) { // libssl.so.<SHLIB_VERSION_NUMBER> and libcrypto.so.<SHLIB_VERSION_NUMBER> found - return pair; + return result; } else { libssl->unload(); libcrypto->unload(); @@ -862,7 +866,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl() libssl->setFileNameAndVersion(QLatin1String("ssl"), fallbackSoname); libcrypto->setFileNameAndVersion(QLatin1String("crypto"), fallbackSoname); if (libcrypto->load() && libssl->load()) { - return pair; + return result; } else { libssl->unload(); libcrypto->unload(); @@ -899,7 +903,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl() # endif if (libcrypto->load() && libssl->load()) { // libssl.so.0 and libcrypto.so.0 found - return pair; + return result; } else { libssl->unload(); libcrypto->unload(); @@ -924,7 +928,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl() if (libssl->load()) { // libssl.so.x and libcrypto.so.x found - return pair; + return result; } else { libssl->unload(); } @@ -934,41 +938,33 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl() } // failed to load anything - delete libssl; - delete libcrypto; - libssl = libcrypto = 0; - return pair; + result = {}; + return result; # else // not implemented for this platform yet - return pair; + return result; # endif } #endif +static QBasicMutex symbolResolveMutex; +static QBasicAtomicInt symbolsResolved = Q_BASIC_ATOMIC_INITIALIZER(false); +static bool triedToResolveSymbols = false; + bool q_resolveOpenSslSymbols() { - static bool symbolsResolved = false; - static bool triedToResolveSymbols = false; -#if QT_CONFIG(thread) -#if QT_CONFIG(opensslv11) - QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_OPENSSL_init_ssl)); -#else - QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init)); -#endif -#endif - if (symbolsResolved) + if (symbolsResolved.loadAcquire()) + return true; + QMutexLocker locker(&symbolResolveMutex); + if (symbolsResolved.loadRelaxed()) return true; if (triedToResolveSymbols) return false; triedToResolveSymbols = true; -#ifdef Q_OS_WIN - QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32(); -#else - QPair<QLibrary *, QLibrary *> libs = loadOpenSsl(); -#endif - if (!libs.first || !libs.second) + LoadedOpenSsl libs = loadOpenSsl(); + if (!libs.ssl || !libs.crypto) // failed to load them return false; @@ -978,6 +974,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(OPENSSL_init_crypto) RESOLVEFUNC(ASN1_STRING_get0_data) RESOLVEFUNC(EVP_CIPHER_CTX_reset) + RESOLVEFUNC(EVP_PKEY_up_ref) RESOLVEFUNC(EVP_PKEY_base_id) RESOLVEFUNC(RSA_bits) RESOLVEFUNC(OPENSSL_sk_new_null) @@ -1016,8 +1013,6 @@ bool q_resolveOpenSslSymbols() if (!_q_OpenSSL_version) { // Apparently, we were built with OpenSSL 1.1 enabled but are now using // a wrong library. - delete libs.first; - delete libs.second; qCWarning(lcSsl, "Incompatible version of OpenSSL"); return false; } @@ -1139,8 +1134,6 @@ bool q_resolveOpenSslSymbols() // OpenSSL 1.1 has deprecated and removed SSLeay. We consider a failure to // resolve this symbol as a failure to resolve symbols. // The right operand of '||' above is ... a bit of paranoia. - delete libs.first; - delete libs.second; qCWarning(lcSsl, "Incompatible version of OpenSSL"); return false; } @@ -1204,6 +1197,11 @@ bool q_resolveOpenSslSymbols() #ifndef OPENSSL_NO_RC2 RESOLVEFUNC(EVP_rc2_cbc) #endif +#ifndef OPENSSL_NO_AES + RESOLVEFUNC(EVP_aes_128_cbc) + RESOLVEFUNC(EVP_aes_192_cbc) + RESOLVEFUNC(EVP_aes_256_cbc) +#endif RESOLVEFUNC(EVP_sha1) RESOLVEFUNC(EVP_PKEY_assign) RESOLVEFUNC(EVP_PKEY_set1_RSA) @@ -1212,6 +1210,7 @@ bool q_resolveOpenSslSymbols() #ifndef OPENSSL_NO_EC RESOLVEFUNC(EVP_PKEY_set1_EC_KEY) #endif + RESOLVEFUNC(EVP_PKEY_cmp) RESOLVEFUNC(EVP_PKEY_free) RESOLVEFUNC(EVP_PKEY_get1_DSA) RESOLVEFUNC(EVP_PKEY_get1_RSA) @@ -1405,9 +1404,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(d2i_PKCS12_bio) RESOLVEFUNC(PKCS12_free) - symbolsResolved = true; - delete libs.first; - delete libs.second; + symbolsResolved.storeRelease(true); return true; } #endif // QT_CONFIG(library) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 7b604b2ab8..69b2b90fbd 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -281,14 +281,20 @@ const EVP_CIPHER *q_EVP_des_ede3_cbc(); #ifndef OPENSSL_NO_RC2 const EVP_CIPHER *q_EVP_rc2_cbc(); #endif +#ifndef OPENSSL_NO_AES +const EVP_CIPHER *q_EVP_aes_128_cbc(); +const EVP_CIPHER *q_EVP_aes_192_cbc(); +const EVP_CIPHER *q_EVP_aes_256_cbc(); +#endif Q_AUTOTEST_EXPORT const EVP_MD *q_EVP_sha1(); int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c); Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b); -int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); -int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b); +Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); +Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b); #ifndef OPENSSL_NO_EC -int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b); +Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b); #endif +Q_AUTOTEST_EXPORT int q_EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); Q_AUTOTEST_EXPORT void q_EVP_PKEY_free(EVP_PKEY *a); RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a); DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a); diff --git a/src/network/ssl/qsslsocket_opensslpre11.cpp b/src/network/ssl/qsslsocket_opensslpre11.cpp index f5aab821ea..2af437f0fa 100644 --- a/src/network/ssl/qsslsocket_opensslpre11.cpp +++ b/src/network/ssl/qsslsocket_opensslpre11.cpp @@ -67,7 +67,6 @@ #include <QtCore/qthread.h> #include <QtCore/qfile.h> #include <QtCore/qmutex.h> -#include <QtCore/qlibrary.h> QT_BEGIN_NAMESPACE diff --git a/src/network/ssl/qsslsocket_qt.cpp b/src/network/ssl/qsslsocket_qt.cpp index b0fb60ea76..9ff9a66c05 100644 --- a/src/network/ssl/qsslsocket_qt.cpp +++ b/src/network/ssl/qsslsocket_qt.cpp @@ -72,6 +72,7 @@ static QAsn1Element _q_PKCS7_data(const QByteArray &data) Some test vectors: http://www.drh-consultancy.demon.co.uk/test.txt + \internal */ static QByteArray _q_PKCS12_keygen(char id, const QByteArray &salt, const QString &passPhrase, int n, int r) { diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index 46c109b6e5..c6e3e4d786 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -435,7 +435,7 @@ QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols) bool QSslSocketPrivate::s_loadRootCertsOnDemand = true; bool QSslSocketPrivate::s_loadedCiphersAndCerts = false; -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_schannel_mutex, (QMutex::Recursive)) +Q_GLOBAL_STATIC(QRecursiveMutex, qt_schannel_mutex) void QSslSocketPrivate::ensureInitialized() { diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index d54ac2ad73..39c1ce55e3 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -177,6 +177,7 @@ void QSslSocketPrivate::ensureInitialized() long QSslSocketPrivate::sslLibraryVersionNumber() { + // ### Qt 6: Find a proper replacement for the deprecated method below. return QSysInfo::windowsVersion(); } |