Details
Description
Running the simplebrowser example that loads http://qt.io on Windows MSVC 2017 64 shows a pop up warning:
Certificate Error The server's certificate was not disclosed via Certificate Transparency. If you wish so, you continue with an unverified certificate. Accepting an unverified certificate mean you may not be connected with the host you tried to connect to. Do you wish to override the security check and continue ? Yes No
This seems to be a regression from Qt 5.9.4.
The culprit here is not the https://qt.io certificate, but an included image from cloudfront.net. Other affected pages are e.g. https://amazon.com .
The issue is with the Certificate Transparency logic in Chromium. Most certificates by Symantec are blacklisted to require Certificate Transparency. Anyhow, because the list of transparency logs in 56 is outdated, the lookup of a certificate might fail, resulting in a user visible warning.
Code flow
This is the stack trace for blacklisting the certificate:
bool TransportSecurityState::ShouldRequireCT( const std::string& hostname, const X509Certificate* validated_certificate_chain, const HashValueVector& public_key_hashes) { ... // No exception found. This certificate must conform to the CT policy. return true; // break here ... } 1 net::TransportSecurityState::ShouldRequireCT transport_security_state.cc 908 0x182042605 2 net::SSLClientSocketImpl::VerifyCT ssl_client_socket_impl.cc 1579 0x182241397 3 net::SSLClientSocketImpl::DoVerifyCertComplete ssl_client_socket_impl.cc 1265 0x18223bd5a 4 net::SSLClientSocketImpl::DoHandshakeLoop ssl_client_socket_impl.cc 1362 0x18223a9df 5 net::SSLClientSocketImpl::OnHandshakeIOComplete ssl_client_socket_impl.cc 1325 0x18223f2eb 6 base::internal::FunctorTraits<void (__cdecl discardable_memory::DiscardableSharedMemoryManager:: *)(enum base::MemoryPressureListener::MemoryPressureLevel) __ptr64,void>::Invoke<discardable_memory::DiscardableSharedMemoryManager * __ptr64,enu bind_internal.h 215 0x182cfa2a7 7 base::internal::InvokeHelper<0,void>::MakeItSo<void (__cdecl content::MojoAsyncResourceHandler:: *const & __ptr64)(unsigned int) __ptr64,content::MojoAsyncResourceHandler * __ptr64,unsigned int> bind_internal.h 287 0x180ad9319 8 base::internal::Invoker<base::internal::BindState<void (__cdecl content::MojoAsyncResourceHandler:: *)(unsigned int) __ptr64,base::internal::UnretainedWrapper<content::MojoAsyncResourceHandler>>,void __cdecl(unsigned int)>::RunImpl<void (__c bind_internal.h 365 0x180ad9385 9 base::internal::Invoker<base::internal::BindState<void (__cdecl content::MojoAsyncResourceHandler:: *)(unsigned int) __ptr64,base::internal::UnretainedWrapper<content::MojoAsyncResourceHandler>>,void __cdecl(unsigned int)>::Run bind_internal.h 343 0x180adc252 10 base::internal::RunMixin<base::Callback<void __cdecl(enum content::PushDeliveryStatus),1,1>>::Run callback.h 65 0x180c0e17f 11 net::CachingCertVerifier::OnRequestFinished caching_cert_verifier.cc 145 0x18217be3e 12 base::internal::FunctorTraits<void (__cdecl net::CachingCertVerifier:: *)(net::CertVerifier::RequestParams const & __ptr64,base::Time,base::Callback<void __cdecl(int),1,1> const & __ptr64,net::CertVerifyResult * __ptr64,int) __ptr64,void>::In bind_internal.h 215 0x182179c80 13 base::internal::InvokeHelper<0,void>::MakeItSo<void (__cdecl net::CachingCertVerifier:: *const & __ptr64)(net::CertVerifier::RequestParams const & __ptr64,base::Time,base::Callback<void __cdecl(int),1,1> const & __ptr64,net::CertVerifyResult bind_internal.h 287 0x182179d78 14 base::internal::Invoker<base::internal::BindState<void (__cdecl net::CachingCertVerifier:: *)(net::CertVerifier::RequestParams const & __ptr64,base::Time,base::Callback<void __cdecl(int),1,1> const & __ptr64,net::CertVerifyResult * __ptr64,in bind_internal.h 365 0x182179eac 15 base::internal::Invoker<base::internal::BindState<void (__cdecl net::CachingCertVerifier:: *)(net::CertVerifier::RequestParams const & __ptr64,base::Time,base::Callback<void __cdecl(int),1,1> const & __ptr64,net::CertVerifyResult * __ptr64,in bind_internal.h 343 0x18217c042 16 base::internal::RunMixin<base::Callback<void __cdecl(enum content::PushDeliveryStatus),1,1>>::Run callback.h 65 0x180c0e17f 17 net::CertVerifierRequest::Post multi_threaded_cert_verifier.cc 164 0x1821836a6 18 net::CertVerifierJob::OnJobCompleted multi_threaded_cert_verifier.cc 325 0x18218352e 19 base::internal::FunctorTraits<void (__cdecl net::CertVerifierJob:: *)(std::unique_ptr<net::`anonymous namespace'::ResultHelper,std::default_delete<net::`anonymous namespace'::ResultHelper>>) __ptr64,void>::Invoke<base::WeakPtr<net::CertVerif bind_internal.h 215 0x18217eaaf 20 base::internal::InvokeHelper<1,void>::MakeItSo<void (__cdecl net::CertVerifierJob:: *const & __ptr64)(std::unique_ptr<net::`anonymous namespace'::ResultHelper,std::default_delete<net::`anonymous namespace'::ResultHelper>>) __ptr64,base::Weak bind_internal.h 308 0x18217ed96 ... <More>
Workarounds
Certificate errors can be explicitly overridden:
bool WebPage::certificateError(const QWebEngineCertificateError &error) { if (error.error() == QWebEngineCertificateError::CertificateTransparencyRequired) return true; }
onCertificateError: function(error) {
if (error.error === WebEngineCertificateError.CertificateTransparencyRequired)
error.ignoreCertificateError();
}