From e6bccb1f0d8ca59acb1ffdac74a823c06346e7f3 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Mon, 16 Nov 2015 15:02:37 +0100 Subject: [PATCH] Remove legacy platform code in QSslSocket for OS X < 10.5 This avoids manual symbol lookups and makes the code more readable. Mark identical code. Also use smart pointers instead of manual memory management. (Backport of d42d7781f1cd62c3c7c008859507f24a1ff5bb2a to Qt 5.4) Change-Id: I62820313dce87de6623cdc87b6e1361200ed7822 Reviewed-by: Markus Goetz (Woboq GmbH) Conflicts: src/network/ssl/qsslsocket_openssl.cpp --- src/network/ssl/qsslsocket_openssl.cpp | 81 +++++++++++----------------------- src/network/ssl/qsslsocket_p.h | 6 +-- 2 files changed, 26 insertions(+), 61 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 82644c1..415f147 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -76,14 +76,17 @@ #include +#ifdef Q_OS_DARWIN +# include +#endif + +#ifdef Q_OS_OSX +# include +#endif + QT_BEGIN_NAMESPACE -#if defined(Q_OS_MACX) -#define kSecTrustSettingsDomainSystem 2 // so we do not need to include the header file - PtrSecCertificateCopyData QSslSocketPrivate::ptrSecCertificateCopyData = 0; - PtrSecTrustSettingsCopyCertificates QSslSocketPrivate::ptrSecTrustSettingsCopyCertificates = 0; - PtrSecTrustCopyAnchorCertificates QSslSocketPrivate::ptrSecTrustCopyAnchorCertificates = 0; -#elif defined(Q_OS_WIN) +#if defined(Q_OS_WIN) PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = 0; PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = 0; PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = 0; @@ -509,23 +512,7 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded() #ifndef QT_NO_LIBRARY //load symbols needed to receive certificates from system store -#if defined(Q_OS_MACX) - QLibrary securityLib("/System/Library/Frameworks/Security.framework/Versions/Current/Security"); - if (securityLib.load()) { - ptrSecCertificateCopyData = (PtrSecCertificateCopyData) securityLib.resolve("SecCertificateCopyData"); - if (!ptrSecCertificateCopyData) - qCWarning(lcSsl, "could not resolve symbols in security library"); // should never happen - - ptrSecTrustSettingsCopyCertificates = (PtrSecTrustSettingsCopyCertificates) securityLib.resolve("SecTrustSettingsCopyCertificates"); - if (!ptrSecTrustSettingsCopyCertificates) { // method was introduced in Leopard, use legacy method if it's not there - ptrSecTrustCopyAnchorCertificates = (PtrSecTrustCopyAnchorCertificates) securityLib.resolve("SecTrustCopyAnchorCertificates"); - if (!ptrSecTrustCopyAnchorCertificates) - qCWarning(lcSsl, "could not resolve symbols in security library"); // should never happen - } - } else { - qCWarning(lcSsl, "could not load security library"); - } -#elif defined(Q_OS_WIN) +#if defined(Q_OS_WIN) HINSTANCE hLib = LoadLibraryW(L"Crypt32"); if (hLib) { #if defined(Q_OS_WINCE) @@ -693,40 +680,22 @@ QList QSslSocketPrivate::systemCaCertificates() timer.start(); #endif QList systemCerts; -#if defined(Q_OS_MACX) - CFArrayRef cfCerts; - OSStatus status = 1; - - CFDataRef SecCertificateCopyData ( - SecCertificateRef certificate - ); - - if (ptrSecCertificateCopyData) { - if (ptrSecTrustSettingsCopyCertificates) - status = ptrSecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts); - else if (ptrSecTrustCopyAnchorCertificates) - status = ptrSecTrustCopyAnchorCertificates(&cfCerts); - if (!status) { - CFIndex size = CFArrayGetCount(cfCerts); - for (CFIndex i = 0; i < size; ++i) { - SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i); - CFDataRef data; - - data = ptrSecCertificateCopyData(cfCert); - - if (data == NULL) { - qCWarning(lcSsl, "error retrieving a CA certificate from the system store"); - } else { - QByteArray rawCert = QByteArray::fromRawData((const char *)CFDataGetBytePtr(data), CFDataGetLength(data)); - systemCerts.append(QSslCertificate::fromData(rawCert, QSsl::Der)); - CFRelease(data); - } + // note: also check implementation in openssl_mac.cpp +#if defined(Q_OS_OSX) + // SecTrustSettingsCopyCertificates is not defined on iOS. + QCFType cfCerts; + + OSStatus status = SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts); + if (status == noErr ) { + const CFIndex size = CFArrayGetCount(cfCerts); + for (CFIndex i = 0; i < size; ++i) { + SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i); + QCFType derData = SecCertificateCopyData(cfCert); + if (derData == NULL) { + qWarning("error retrieving a CA certificate from the system store"); + } else { + systemCerts << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der); } - CFRelease(cfCerts); - } - else { - // no detailed error handling here - qCWarning(lcSsl, "could not retrieve system CA certificates"); } } #elif defined(Q_OS_WIN) diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index d651971..17cc7b4 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -151,11 +151,7 @@ public: static bool isMatchingHostname(const QSslCertificate &cert, const QString &peerName); Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname); -#if defined(Q_OS_MACX) - static PtrSecCertificateCopyData ptrSecCertificateCopyData; - static PtrSecTrustSettingsCopyCertificates ptrSecTrustSettingsCopyCertificates; - static PtrSecTrustCopyAnchorCertificates ptrSecTrustCopyAnchorCertificates; -#elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) static PtrCertOpenSystemStoreW ptrCertOpenSystemStoreW; static PtrCertFindCertificateInStore ptrCertFindCertificateInStore; static PtrCertCloseStore ptrCertCloseStore;