diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2017-06-01 12:04:06 +0200 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2017-06-02 12:34:22 +0000 |
commit | 4fb174563945438d34da38ebadf0f6b03cad266d (patch) | |
tree | 7188f1eae23d20400f9445544bc64962959263de /src/network/ssl | |
parent | 91ef71b7bf3526a0bb7f6f83e6b3e03e286c2030 (diff) |
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 <edward.welbourne@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/network/ssl')
-rw-r--r-- | src/network/ssl/qsslsocket_mac.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
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<SecCertificateRef> 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); |