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>
This commit is contained in:
parent
5a48d1d164
commit
7cfc24f72a
@ -51,8 +51,91 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include <QtCore/private/qcore_mac_p.h>
|
||||||
|
|
||||||
|
#ifdef Q_OS_OSX
|
||||||
|
#include <CoreServices/CoreServices.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
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))
|
Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_securetransport_mutex, (QMutex::Recursive))
|
||||||
|
|
||||||
//#define QSSLSOCKET_DEBUG
|
//#define QSSLSOCKET_DEBUG
|
||||||
@ -140,7 +223,7 @@ void QSslSocketPrivate::ensureInitialized()
|
|||||||
// from QSslCertificatePrivate's ctor.
|
// from QSslCertificatePrivate's ctor.
|
||||||
s_loadedCiphersAndCerts = true;
|
s_loadedCiphersAndCerts = true;
|
||||||
|
|
||||||
QCFType<SSLContextRef> context(SSLCreateContext(Q_NULLPTR, kSSLClientSide, kSSLStreamType));
|
const QSecureTransportContext context(qt_createSecureTransportContext(QSslSocket::SslClientMode));
|
||||||
if (context) {
|
if (context) {
|
||||||
QList<QSslCipher> ciphers;
|
QList<QSslCipher> ciphers;
|
||||||
QList<QSslCipher> defaultCiphers;
|
QList<QSslCipher> defaultCiphers;
|
||||||
@ -167,7 +250,6 @@ void QSslSocketPrivate::ensureInitialized()
|
|||||||
if (!s_loadRootCertsOnDemand)
|
if (!s_loadRootCertsOnDemand)
|
||||||
setDefaultCaCertificates(systemCaCertificates());
|
setDefaultCaCertificates(systemCaCertificates());
|
||||||
} else {
|
} else {
|
||||||
qCWarning(lcSsl) << "SSLCreateContext failed";
|
|
||||||
s_loadedCiphersAndCerts = false;
|
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_X(!context, Q_FUNC_INFO, "invalid socket state, context is not null");
|
||||||
Q_ASSERT(plainSocket);
|
Q_ASSERT(plainSocket);
|
||||||
|
|
||||||
SSLProtocolSide side = kSSLClientSide;
|
context.reset(qt_createSecureTransportContext(mode));
|
||||||
if (mode == QSslSocket::SslServerMode)
|
|
||||||
side = kSSLServerSide;
|
|
||||||
|
|
||||||
context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
setError("SSLCreateContext failed", QAbstractSocket::SslInternalError);
|
setError("SSLCreateContext failed", QAbstractSocket::SslInternalError);
|
||||||
return false;
|
return false;
|
||||||
@ -752,7 +830,7 @@ bool QSslSocketBackendPrivate::initSslContext()
|
|||||||
|
|
||||||
void QSslSocketBackendPrivate::destroySslContext()
|
void QSslSocketBackendPrivate::destroySslContext()
|
||||||
{
|
{
|
||||||
context = Q_NULLPTR;
|
context.reset(Q_NULLPTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase);
|
static QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase);
|
||||||
|
@ -45,8 +45,6 @@
|
|||||||
// We mean it.
|
// We mean it.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <QtCore/private/qcore_mac_p.h>
|
|
||||||
|
|
||||||
#include <QtCore/qstring.h>
|
#include <QtCore/qstring.h>
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include <QtCore/qlist.h>
|
#include <QtCore/qlist.h>
|
||||||
@ -59,6 +57,20 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
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
|
class QSslSocketBackendPrivate : public QSslSocketPrivate
|
||||||
{
|
{
|
||||||
Q_DECLARE_PUBLIC(QSslSocket)
|
Q_DECLARE_PUBLIC(QSslSocket)
|
||||||
@ -76,8 +88,8 @@ public:
|
|||||||
void startServerEncryption() Q_DECL_OVERRIDE;
|
void startServerEncryption() Q_DECL_OVERRIDE;
|
||||||
void transmit() Q_DECL_OVERRIDE;
|
void transmit() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
static QList<QSslError> (verify)(QList<QSslCertificate> certificateChain,
|
static QList<QSslError> verify(QList<QSslCertificate> certificateChain,
|
||||||
const QString &hostName);
|
const QString &hostName);
|
||||||
|
|
||||||
static bool importPkcs12(QIODevice *device,
|
static bool importPkcs12(QIODevice *device,
|
||||||
QSslKey *key, QSslCertificate *cert,
|
QSslKey *key, QSslCertificate *cert,
|
||||||
@ -108,7 +120,7 @@ private:
|
|||||||
void setError(const QString &errorString,
|
void setError(const QString &errorString,
|
||||||
QAbstractSocket::SocketError errorCode);
|
QAbstractSocket::SocketError errorCode);
|
||||||
|
|
||||||
mutable QCFType<SSLContextRef> context;
|
QSecureTransportContext context;
|
||||||
|
|
||||||
Q_DISABLE_COPY(QSslSocketBackendPrivate);
|
Q_DISABLE_COPY(QSslSocketBackendPrivate);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user