From 4fb174563945438d34da38ebadf0f6b03cad266d Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 1 Jun 2017 12:04:06 +0200 Subject: Ssl socket - fix broken certificate verification On iOS QSslConfiguration always has an empty list of system CA certificates. Calling SecTrustSetAnchorCertificatesOnly(.., TRUE) on iOS results in SecTrustEvaluate failing to verify a valid certificate, since there are no 'anchors' at all. We can use SecTrustSetAnchorCerificatesOnly(.. TRUE) on macOS only, where we do extract/copy system certificates using SecTrustSettingsCopyCertificates and save them in a QSslConfiguration's list. Task-number: QTBUG-61053 Change-Id: I70d4e46273d78414baaac8531273def707c3eebc Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_mac.cpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'src/network/ssl/qsslsocket_mac.cpp') diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index fec5fbefc0..78aceadb81 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -1222,9 +1222,32 @@ bool QSslSocketBackendPrivate::verifyPeerTrust() QCFType certRef = SecCertificateCreateWithData(NULL, certData); CFArrayAppendValue(certArray, certRef); } + SecTrustSetAnchorCertificates(trust, certArray); - // Secure Transport should use anchors only from our QSslConfiguration: - SecTrustSetAnchorCertificatesOnly(trust, true); + + // By default SecTrustEvaluate uses both CA certificates provided in + // QSslConfiguration and the ones from the system database. This behavior can + // be unexpected if a user's code tries to limit the trusted CAs to those + // explicitly set in QSslConfiguration. + // Since on macOS we initialize the default QSslConfiguration copying the + // system CA certificates (using SecTrustSettingsCopyCertificates) we can + // call SecTrustSetAnchorCertificatesOnly(trust, true) to force SecTrustEvaluate + // to use anchors only from our QSslConfiguration. + // Unfortunately, SecTrustSettingsCopyCertificates is not available on iOS + // and the default QSslConfiguration always has an empty list of system CA + // certificates. This leaves no way to provide client code with access to the + // actual system CA certificate list (which most use-cases need) other than + // by letting SecTrustEvaluate fall through to the system list; so, in this case + // (even though the client code may have provided its own certs), we retain + // the default behavior. + +#ifdef Q_OS_MACOS + const bool anchorsFromConfigurationOnly = true; +#else + const bool anchorsFromConfigurationOnly = false; +#endif + + SecTrustSetAnchorCertificatesOnly(trust, anchorsFromConfigurationOnly); SecTrustResultType trustResult = kSecTrustResultInvalid; SecTrustEvaluate(trust, &trustResult); -- cgit v1.2.3