summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@theqtcompany.com>2015-09-29 12:38:53 +0200
committerMorten Johan Sørvig <morten.sorvig@theqtcompany.com>2015-11-23 10:46:49 +0000
commit7cfc24f72a80656580218dccab9b24b89a273022 (patch)
treecec3a0e23192b157cf0378a9bafb62aa9a8add14
parent5a48d1d164ba507469ee1a8a682a3c194d733890 (diff)
Secure Transport backend - make it work on OS X 10.7
On OS X SSLCreateContext is quite recent - it requires OS X/SDK version >= 10.8. Since SecureTransport back-end is the default one in Qt 5.6, make it also work on OS X 10.7. Change-Id: I364feff9dd95772fcea926494b2d4edaffd2dde1 Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com>
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp94
-rw-r--r--src/network/ssl/qsslsocket_mac_p.h22
2 files changed, 103 insertions, 13 deletions
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index b83e56c29e..6d7a26e1c0 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -51,8 +51,91 @@
#include <algorithm>
#include <cstddef>
+#include <QtCore/private/qcore_mac_p.h>
+
+#ifdef Q_OS_OSX
+#include <CoreServices/CoreServices.h>
+#endif
+
QT_BEGIN_NAMESPACE
+static SSLContextRef qt_createSecureTransportContext(QSslSocket::SslMode mode)
+{
+ const bool isServer = mode == QSslSocket::SslServerMode;
+ SSLContextRef context = Q_NULLPTR;
+
+#ifndef Q_OS_OSX
+ const SSLProtocolSide side = isServer ? kSSLServerSide : kSSLClientSide;
+ // We never use kSSLDatagramType, so it's kSSLStreamType unconditionally.
+ context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
+ if (!context)
+ qCWarning(lcSsl) << "SSLCreateContext failed";
+#else // Q_OS_OSX
+
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ const SSLProtocolSide side = isServer ? kSSLServerSide : kSSLClientSide;
+ // We never use kSSLDatagramType, so it's kSSLStreamType unconditionally.
+ context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
+ if (!context)
+ qCWarning(lcSsl) << "SSLCreateContext failed";
+ } else {
+#else
+ {
+#endif
+ const OSStatus errCode = SSLNewContext(isServer, &context);
+ if (errCode != noErr || !context)
+ qCWarning(lcSsl) << "SSLNewContext failed with error:" << errCode;
+ }
+#endif // !Q_OS_OSX
+
+ return context;
+}
+
+static void qt_releaseSecureTransportContext(SSLContextRef context)
+{
+ if (!context)
+ return;
+
+#ifndef Q_OS_OSX
+ CFRelease(context);
+#else
+
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ CFRelease(context);
+ } else {
+#else
+ {
+#endif
+ const OSStatus errCode = SSLDisposeContext(context);
+ if (errCode != noErr)
+ qCWarning(lcSsl) << "SSLDisposeContext failed with error:" << errCode;
+ }
+#endif // !Q_OS_OSX
+}
+
+QSecureTransportContext::QSecureTransportContext(SSLContextRef c)
+ : context(c)
+{
+}
+
+QSecureTransportContext::~QSecureTransportContext()
+{
+ qt_releaseSecureTransportContext(context);
+}
+
+QSecureTransportContext::operator SSLContextRef()const
+{
+ return context;
+}
+
+void QSecureTransportContext::reset(SSLContextRef newContext)
+{
+ qt_releaseSecureTransportContext(context);
+ context = newContext;
+}
+
Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_securetransport_mutex, (QMutex::Recursive))
//#define QSSLSOCKET_DEBUG
@@ -140,7 +223,7 @@ void QSslSocketPrivate::ensureInitialized()
// from QSslCertificatePrivate's ctor.
s_loadedCiphersAndCerts = true;
- QCFType<SSLContextRef> context(SSLCreateContext(Q_NULLPTR, kSSLClientSide, kSSLStreamType));
+ const QSecureTransportContext context(qt_createSecureTransportContext(QSslSocket::SslClientMode));
if (context) {
QList<QSslCipher> ciphers;
QList<QSslCipher> defaultCiphers;
@@ -167,7 +250,6 @@ void QSslSocketPrivate::ensureInitialized()
if (!s_loadRootCertsOnDemand)
setDefaultCaCertificates(systemCaCertificates());
} else {
- qCWarning(lcSsl) << "SSLCreateContext failed";
s_loadedCiphersAndCerts = false;
}
@@ -652,11 +734,7 @@ bool QSslSocketBackendPrivate::initSslContext()
Q_ASSERT_X(!context, Q_FUNC_INFO, "invalid socket state, context is not null");
Q_ASSERT(plainSocket);
- SSLProtocolSide side = kSSLClientSide;
- if (mode == QSslSocket::SslServerMode)
- side = kSSLServerSide;
-
- context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
+ context.reset(qt_createSecureTransportContext(mode));
if (!context) {
setError("SSLCreateContext failed", QAbstractSocket::SslInternalError);
return false;
@@ -752,7 +830,7 @@ bool QSslSocketBackendPrivate::initSslContext()
void QSslSocketBackendPrivate::destroySslContext()
{
- context = Q_NULLPTR;
+ context.reset(Q_NULLPTR);
}
static QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase);
diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h
index 868b816957..0479e30d97 100644
--- a/src/network/ssl/qsslsocket_mac_p.h
+++ b/src/network/ssl/qsslsocket_mac_p.h
@@ -45,8 +45,6 @@
// We mean it.
//
-#include <QtCore/private/qcore_mac_p.h>
-
#include <QtCore/qstring.h>
#include <QtCore/qglobal.h>
#include <QtCore/qlist.h>
@@ -59,6 +57,20 @@
QT_BEGIN_NAMESPACE
+class QSecureTransportContext
+{
+public:
+ explicit QSecureTransportContext(SSLContextRef context);
+ ~QSecureTransportContext();
+
+ operator SSLContextRef () const;
+ void reset(SSLContextRef newContext);
+private:
+ SSLContextRef context;
+
+ Q_DISABLE_COPY(QSecureTransportContext);
+};
+
class QSslSocketBackendPrivate : public QSslSocketPrivate
{
Q_DECLARE_PUBLIC(QSslSocket)
@@ -76,8 +88,8 @@ public:
void startServerEncryption() Q_DECL_OVERRIDE;
void transmit() Q_DECL_OVERRIDE;
- static QList<QSslError> (verify)(QList<QSslCertificate> certificateChain,
- const QString &hostName);
+ static QList<QSslError> verify(QList<QSslCertificate> certificateChain,
+ const QString &hostName);
static bool importPkcs12(QIODevice *device,
QSslKey *key, QSslCertificate *cert,
@@ -108,7 +120,7 @@ private:
void setError(const QString &errorString,
QAbstractSocket::SocketError errorCode);
- mutable QCFType<SSLContextRef> context;
+ QSecureTransportContext context;
Q_DISABLE_COPY(QSslSocketBackendPrivate);
};