Make WKWebView._negotiatedLegacyTLS accurate when loading main resouorce from network...
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Feb 2020 21:07:48 +0000 (21:07 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Feb 2020 21:07:48 +0000 (21:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=207207

Reviewed by Chris Dumez.

Source/WebCore:

* platform/network/ResourceResponseBase.cpp:
(WebCore::ResourceResponseBase::includeCertificateInfo const):
* platform/network/ResourceResponseBase.h:
(WebCore::ResourceResponseBase::usedLegacyTLS const):
(WebCore::ResourceResponseBase::encode const):
(WebCore::ResourceResponseBase::decode):

Source/WebKit:

In PageLoadState::didCommitLoad, I was resetting the value of _negotiatedLegacyTLS to false.
That created a race condition when loading the main resource because the NetworkProcess would
message the UIProcess setting _negotiatedLegacyTLS to false, while the NetworkProcess would
message the WebProcess which would message the UIProcess to call PageLoadState::didCommitLoad
which would reset it to false.  Now it resets it to the correct value, whatever it is.

Updating the ResourceResponseBase serialization code has the desirable side effect that the disk
cache will remember whether legacy TLS was used to fetch each resource.  This will make it so
_negotiatedLegacyTLS is true if we read content from the disk cache that was originally fetched
using legacy TLS.

In order to not increase the memory footprint of ResourceResponse, I changed m_httpStatusCode from
an int to a short.  It just needs to be able to cover the values 0-600 or so, which really only needs 10 bits.

Covered by new API tests.

* NetworkProcess/NetworkCORSPreflightChecker.cpp:
(WebKit::NetworkCORSPreflightChecker::didReceiveResponse):
* NetworkProcess/NetworkCORSPreflightChecker.h:
* NetworkProcess/NetworkDataTask.cpp:
(WebKit::NetworkDataTask::didReceiveResponse):
(WebKit::NetworkDataTask::negotiatedLegacyTLS const): Deleted.
* NetworkProcess/NetworkDataTask.h:
(WebKit::NetworkDataTaskClient::negotiatedLegacyTLS const): Deleted.
* NetworkProcess/NetworkDataTaskBlob.cpp:
(WebKit::NetworkDataTaskBlob::dispatchDidReceiveResponse):
* NetworkProcess/NetworkLoad.cpp:
(WebKit::NetworkLoad::didReceiveResponse):
(WebKit::NetworkLoad::notifyDidReceiveResponse):
(WebKit::NetworkLoad::throttleDelayCompleted):
(WebKit::NetworkLoad::negotiatedLegacyTLS const): Deleted.
* NetworkProcess/NetworkLoad.h:
* NetworkProcess/NetworkResourceLoader.h:
* NetworkProcess/PingLoad.cpp:
(WebKit::PingLoad::didReceiveResponse):
* NetworkProcess/PingLoad.h:
* NetworkProcess/cocoa/NetworkDataTaskCocoa.h:
* NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::NetworkDataTaskCocoa::didReceiveResponse):
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
* NetworkProcess/curl/NetworkDataTaskCurl.cpp:
(WebKit::NetworkDataTaskCurl::invokeDidReceiveResponse):
* NetworkProcess/soup/NetworkDataTaskSoup.cpp:
(WebKit::NetworkDataTaskSoup::dispatchDidReceiveResponse):
* UIProcess/PageLoadState.cpp:
(WebKit::PageLoadState::didCommitLoad):
* UIProcess/PageLoadState.h:
* UIProcess/ProvisionalPageProxy.cpp:
(WebKit::ProvisionalPageProxy::didCommitLoadForFrame):
* UIProcess/ProvisionalPageProxy.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::commitProvisionalPage):
(WebKit::WebPageProxy::didCommitLoadForFrame):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDidCommitLoad):

Source/WTF:

* wtf/persistence/PersistentDecoder.cpp:
(WTF::Persistence::Decoder::decode):
* wtf/persistence/PersistentDecoder.h:
* wtf/persistence/PersistentEncoder.cpp:
(WTF::Persistence::Encoder::encode):
* wtf/persistence/PersistentEncoder.h:

Tools:

HTTPServer now supports HTTPS. Tell your friends!

* TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm:
(testCertificate):
(testIdentity):
(credentialWithIdentity):
* TestWebKitAPI/Tests/WebKitCocoa/TLSDeprecation.mm:
(TestWebKitAPI::webViewWithNavigationDelegate):
(TestWebKitAPI::TEST):
* TestWebKitAPI/cocoa/HTTPServer.h:
* TestWebKitAPI/cocoa/HTTPServer.mm:
(TestWebKitAPI::HTTPServer::HTTPServer):
(TestWebKitAPI::HTTPServer::request const):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@255846 268f45cc-cd09-0410-ab3c-d52691b4dbfc

38 files changed:
Source/WTF/ChangeLog
Source/WTF/wtf/persistence/PersistentDecoder.cpp
Source/WTF/wtf/persistence/PersistentDecoder.h
Source/WTF/wtf/persistence/PersistentEncoder.cpp
Source/WTF/wtf/persistence/PersistentEncoder.h
Source/WebCore/ChangeLog
Source/WebCore/platform/network/ResourceResponseBase.cpp
Source/WebCore/platform/network/ResourceResponseBase.h
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp
Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h
Source/WebKit/NetworkProcess/NetworkDataTask.cpp
Source/WebKit/NetworkProcess/NetworkDataTask.h
Source/WebKit/NetworkProcess/NetworkDataTaskBlob.cpp
Source/WebKit/NetworkProcess/NetworkLoad.cpp
Source/WebKit/NetworkProcess/NetworkLoad.h
Source/WebKit/NetworkProcess/NetworkResourceLoader.h
Source/WebKit/NetworkProcess/PingLoad.cpp
Source/WebKit/NetworkProcess/PingLoad.h
Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.h
Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.h
Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm
Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
Source/WebKit/UIProcess/PageLoadState.cpp
Source/WebKit/UIProcess/PageLoadState.h
Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
Source/WebKit/UIProcess/ProvisionalPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm
Tools/TestWebKitAPI/Tests/WebKitCocoa/TLSDeprecation.mm
Tools/TestWebKitAPI/cocoa/HTTPServer.h
Tools/TestWebKitAPI/cocoa/HTTPServer.mm

index a9dd77d..6da6d74 100644 (file)
@@ -1,3 +1,17 @@
+2020-02-05  Alex Christensen  <achristensen@webkit.org>
+
+        Make WKWebView._negotiatedLegacyTLS accurate when loading main resouorce from network or cache
+        https://bugs.webkit.org/show_bug.cgi?id=207207
+
+        Reviewed by Chris Dumez.
+
+        * wtf/persistence/PersistentDecoder.cpp:
+        (WTF::Persistence::Decoder::decode):
+        * wtf/persistence/PersistentDecoder.h:
+        * wtf/persistence/PersistentEncoder.cpp:
+        (WTF::Persistence::Encoder::encode):
+        * wtf/persistence/PersistentEncoder.h:
+
 2020-02-05  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r255818.
index 7249f79..f2300a5 100644 (file)
@@ -87,6 +87,11 @@ bool Decoder::decode(uint16_t& result)
     return decodeNumber(result);
 }
 
+bool Decoder::decode(int16_t& result)
+{
+    return decodeNumber(result);
+}
+
 bool Decoder::decode(uint32_t& result)
 {
     return decodeNumber(result);
index 3404f1e..67eb7c4 100644 (file)
@@ -50,6 +50,7 @@ public:
     WTF_EXPORT_PRIVATE bool decode(uint16_t&);
     WTF_EXPORT_PRIVATE bool decode(uint32_t&);
     WTF_EXPORT_PRIVATE bool decode(uint64_t&);
+    WTF_EXPORT_PRIVATE bool decode(int16_t&);
     WTF_EXPORT_PRIVATE bool decode(int32_t&);
     WTF_EXPORT_PRIVATE bool decode(int64_t&);
     WTF_EXPORT_PRIVATE bool decode(float&);
index 8375815..1e1057f 100644 (file)
@@ -85,6 +85,11 @@ void Encoder::encode(uint16_t value)
     encodeNumber(value);
 }
 
+void Encoder::encode(int16_t value)
+{
+    encodeNumber(value);
+}
+
 void Encoder::encode(uint32_t value)
 {
     encodeNumber(value);
index 6daa88a..32c973f 100644 (file)
@@ -85,6 +85,7 @@ private:
     WTF_EXPORT_PRIVATE void encode(uint16_t);
     WTF_EXPORT_PRIVATE void encode(uint32_t);
     WTF_EXPORT_PRIVATE void encode(uint64_t);
+    WTF_EXPORT_PRIVATE void encode(int16_t);
     WTF_EXPORT_PRIVATE void encode(int32_t);
     WTF_EXPORT_PRIVATE void encode(int64_t);
     WTF_EXPORT_PRIVATE void encode(float);
@@ -110,6 +111,7 @@ template <> struct Encoder::Salt<int64_t> { static constexpr unsigned value = 19
 template <> struct Encoder::Salt<float> { static constexpr unsigned value = 23; };
 template <> struct Encoder::Salt<double> { static constexpr unsigned value = 29; };
 template <> struct Encoder::Salt<uint8_t*> { static constexpr unsigned value = 101; };
+template <> struct Encoder::Salt<int16_t> { static constexpr unsigned value = 103; };
 
 template <typename Type>
 void Encoder::updateChecksumForNumber(SHA1& sha1, Type value)
index 9e06604..6bd7539 100644 (file)
@@ -1,3 +1,17 @@
+2020-02-05  Alex Christensen  <achristensen@webkit.org>
+
+        Make WKWebView._negotiatedLegacyTLS accurate when loading main resouorce from network or cache
+        https://bugs.webkit.org/show_bug.cgi?id=207207
+
+        Reviewed by Chris Dumez.
+
+        * platform/network/ResourceResponseBase.cpp:
+        (WebCore::ResourceResponseBase::includeCertificateInfo const):
+        * platform/network/ResourceResponseBase.h:
+        (WebCore::ResourceResponseBase::usedLegacyTLS const):
+        (WebCore::ResourceResponseBase::encode const):
+        (WebCore::ResourceResponseBase::decode):
+
 2020-02-05  Chris Fleizach  <cfleizach@apple.com>
 
         AX: replaceTextInRange should handle when called on the WebArea element
index 7549e51..e9acceb 100644 (file)
@@ -261,11 +261,12 @@ void ResourceResponseBase::setType(Type type)
     m_type = type;
 }
 
-void ResourceResponseBase::includeCertificateInfo() const
+void ResourceResponseBase::includeCertificateInfo(UsedLegacyTLS usedLegacyTLS) const
 {
     if (m_certificateInfo)
         return;
     m_certificateInfo = static_cast<const ResourceResponse*>(this)->platformCertificateInfo();
+    m_usedLegacyTLS = usedLegacyTLS;
 }
 
 String ResourceResponseBase::suggestedFilename() const
index fab1d03..d2b4f1d 100644 (file)
@@ -41,6 +41,8 @@ class ResourceResponse;
 
 bool isScriptAllowedByNosniff(const ResourceResponse&);
 
+enum class UsedLegacyTLS : bool { No, Yes };
+
 // Do not use this class directly, use the class ResourceResponse instead
 class ResourceResponseBase {
     WTF_MAKE_FAST_ALLOCATED;
@@ -127,8 +129,9 @@ public:
     WEBCORE_EXPORT String suggestedFilename() const;
     WEBCORE_EXPORT static String sanitizeSuggestedFilename(const String&);
 
-    WEBCORE_EXPORT void includeCertificateInfo() const;
+    WEBCORE_EXPORT void includeCertificateInfo(UsedLegacyTLS = UsedLegacyTLS::No) const;
     const Optional<CertificateInfo>& certificateInfo() const { return m_certificateInfo; };
+    bool usedLegacyTLS() const { return m_usedLegacyTLS == UsedLegacyTLS::Yes; }
     
     // These functions return parsed values of the corresponding response headers.
     WEBCORE_EXPORT bool cacheControlContainsNoCache() const;
@@ -246,7 +249,8 @@ private:
     bool m_isRangeRequested { false };
 
 protected:
-    int m_httpStatusCode { 0 };
+    short m_httpStatusCode { 0 };
+    mutable UsedLegacyTLS m_usedLegacyTLS { UsedLegacyTLS::No };
 };
 
 inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponseBase::compare(a, b); }
@@ -279,6 +283,7 @@ void ResourceResponseBase::encode(Encoder& encoder) const
     encoder.encodeEnum(m_type);
     encoder.encodeEnum(m_tainting);
     encoder << m_isRedirected;
+    encoder << m_usedLegacyTLS;
     encoder << m_isRangeRequested;
 }
 
@@ -327,7 +332,8 @@ bool ResourceResponseBase::decode(Decoder& decoder, ResourceResponseBase& respon
     if (!decoder.decode(isRedirected))
         return false;
     response.m_isRedirected = isRedirected;
-
+    if (!decoder.decode(response.m_usedLegacyTLS))
+        return false;
     bool isRangeRequested = false;
     if (!decoder.decode(isRangeRequested))
         return false;
index cde55ad..a84479a 100644 (file)
@@ -1,3 +1,69 @@
+2020-02-05  Alex Christensen  <achristensen@webkit.org>
+
+        Make WKWebView._negotiatedLegacyTLS accurate when loading main resouorce from network or cache
+        https://bugs.webkit.org/show_bug.cgi?id=207207
+
+        Reviewed by Chris Dumez.
+
+        In PageLoadState::didCommitLoad, I was resetting the value of _negotiatedLegacyTLS to false.
+        That created a race condition when loading the main resource because the NetworkProcess would
+        message the UIProcess setting _negotiatedLegacyTLS to false, while the NetworkProcess would
+        message the WebProcess which would message the UIProcess to call PageLoadState::didCommitLoad
+        which would reset it to false.  Now it resets it to the correct value, whatever it is.
+
+        Updating the ResourceResponseBase serialization code has the desirable side effect that the disk
+        cache will remember whether legacy TLS was used to fetch each resource.  This will make it so
+        _negotiatedLegacyTLS is true if we read content from the disk cache that was originally fetched
+        using legacy TLS.
+
+        In order to not increase the memory footprint of ResourceResponse, I changed m_httpStatusCode from
+        an int to a short.  It just needs to be able to cover the values 0-600 or so, which really only needs 10 bits.
+
+        Covered by new API tests.
+
+        * NetworkProcess/NetworkCORSPreflightChecker.cpp:
+        (WebKit::NetworkCORSPreflightChecker::didReceiveResponse):
+        * NetworkProcess/NetworkCORSPreflightChecker.h:
+        * NetworkProcess/NetworkDataTask.cpp:
+        (WebKit::NetworkDataTask::didReceiveResponse):
+        (WebKit::NetworkDataTask::negotiatedLegacyTLS const): Deleted.
+        * NetworkProcess/NetworkDataTask.h:
+        (WebKit::NetworkDataTaskClient::negotiatedLegacyTLS const): Deleted.
+        * NetworkProcess/NetworkDataTaskBlob.cpp:
+        (WebKit::NetworkDataTaskBlob::dispatchDidReceiveResponse):
+        * NetworkProcess/NetworkLoad.cpp:
+        (WebKit::NetworkLoad::didReceiveResponse):
+        (WebKit::NetworkLoad::notifyDidReceiveResponse):
+        (WebKit::NetworkLoad::throttleDelayCompleted):
+        (WebKit::NetworkLoad::negotiatedLegacyTLS const): Deleted.
+        * NetworkProcess/NetworkLoad.h:
+        * NetworkProcess/NetworkResourceLoader.h:
+        * NetworkProcess/PingLoad.cpp:
+        (WebKit::PingLoad::didReceiveResponse):
+        * NetworkProcess/PingLoad.h:
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.h:
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+        (WebKit::NetworkDataTaskCocoa::didReceiveResponse):
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
+        * NetworkProcess/curl/NetworkDataTaskCurl.cpp:
+        (WebKit::NetworkDataTaskCurl::invokeDidReceiveResponse):
+        * NetworkProcess/soup/NetworkDataTaskSoup.cpp:
+        (WebKit::NetworkDataTaskSoup::dispatchDidReceiveResponse):
+        * UIProcess/PageLoadState.cpp:
+        (WebKit::PageLoadState::didCommitLoad):
+        * UIProcess/PageLoadState.h:
+        * UIProcess/ProvisionalPageProxy.cpp:
+        (WebKit::ProvisionalPageProxy::didCommitLoadForFrame):
+        * UIProcess/ProvisionalPageProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::commitProvisionalPage):
+        (WebKit::WebPageProxy::didCommitLoadForFrame):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchDidCommitLoad):
+
 2020-02-05  Brady Eidson  <beidson@apple.com>
 
         _WKDownload should expose the originating FrameInfo.
index d5fa8d1..372d968 100644 (file)
@@ -104,7 +104,7 @@ void NetworkCORSPreflightChecker::didReceiveChallenge(WebCore::AuthenticationCha
     m_networkProcess->authenticationManager().didReceiveAuthenticationChallenge(m_parameters.sessionID, m_parameters.webPageProxyID, m_parameters.topOrigin ? &m_parameters.topOrigin->data() : nullptr, challenge, negotiatedLegacyTLS, WTFMove(completionHandler));
 }
 
-void NetworkCORSPreflightChecker::didReceiveResponse(WebCore::ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
+void NetworkCORSPreflightChecker::didReceiveResponse(WebCore::ResourceResponse&& response, NegotiatedLegacyTLS, ResponseCompletionHandler&& completionHandler)
 {
     RELEASE_LOG_IF_ALLOWED("didReceiveResponse");
 
index e4d0857..dad429b 100644 (file)
@@ -69,7 +69,7 @@ public:
 private:
     void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&) final;
     void didReceiveChallenge(WebCore::AuthenticationChallenge&&, NegotiatedLegacyTLS, ChallengeCompletionHandler&&) final;
-    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
+    void didReceiveResponse(WebCore::ResourceResponse&&, NegotiatedLegacyTLS, ResponseCompletionHandler&&) final;
     void didReceiveData(Ref<WebCore::SharedBuffer>&&) final;
     void didCompleteWithError(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&) final;
     void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend) final;
index 62997e8..821236e 100644 (file)
@@ -97,7 +97,7 @@ void NetworkDataTask::scheduleFailure(FailureType type)
     m_failureTimer.startOneShot(0_s);
 }
 
-void NetworkDataTask::didReceiveResponse(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
+void NetworkDataTask::didReceiveResponse(ResourceResponse&& response, NegotiatedLegacyTLS negotiatedLegacyTLS, ResponseCompletionHandler&& completionHandler)
 {
     if (response.isHTTP09()) {
         auto url = response.url();
@@ -111,17 +111,11 @@ void NetworkDataTask::didReceiveResponse(ResourceResponse&& response, ResponseCo
         }
     }
     if (m_client)
-        m_client->didReceiveResponse(WTFMove(response), WTFMove(completionHandler));
+        m_client->didReceiveResponse(WTFMove(response), negotiatedLegacyTLS, WTFMove(completionHandler));
     else
         completionHandler(PolicyAction::Ignore);
 }
 
-void NetworkDataTask::negotiatedLegacyTLS() const
-{
-    if (m_client)
-        m_client->negotiatedLegacyTLS();
-}
-
 bool NetworkDataTask::shouldCaptureExtraNetworkLoadMetrics() const
 {
     return m_client ? m_client->shouldCaptureExtraNetworkLoadMetrics() : false;
index 5dbe7ed..f5b4029 100644 (file)
@@ -62,7 +62,7 @@ class NetworkDataTaskClient {
 public:
     virtual void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&) = 0;
     virtual void didReceiveChallenge(WebCore::AuthenticationChallenge&&, NegotiatedLegacyTLS, ChallengeCompletionHandler&&) = 0;
-    virtual void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) = 0;
+    virtual void didReceiveResponse(WebCore::ResourceResponse&&, NegotiatedLegacyTLS, ResponseCompletionHandler&&) = 0;
     virtual void didReceiveData(Ref<WebCore::SharedBuffer>&&) = 0;
     virtual void didCompleteWithError(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&) = 0;
     virtual void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend) = 0;
@@ -70,7 +70,6 @@ public:
     virtual void cannotShowURL() = 0;
     virtual void wasBlockedByRestrictions() = 0;
 
-    virtual void negotiatedLegacyTLS() const { }
     virtual bool shouldCaptureExtraNetworkLoadMetrics() const { return false; }
 
     void didCompleteWithError(const WebCore::ResourceError& error)
@@ -92,8 +91,7 @@ public:
     virtual void resume() = 0;
     virtual void invalidateAndCancel() = 0;
 
-    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&);
-    void negotiatedLegacyTLS() const;
+    void didReceiveResponse(WebCore::ResourceResponse&&, NegotiatedLegacyTLS, ResponseCompletionHandler&&);
     bool shouldCaptureExtraNetworkLoadMetrics() const;
 
     enum class State {
index b756b8d..a39a225 100644 (file)
@@ -290,7 +290,7 @@ void NetworkDataTaskBlob::dispatchDidReceiveResponse(Error errorCode)
         break;
     }
 
-    didReceiveResponse(WTFMove(response), [this, protectedThis = WTFMove(protectedThis), errorCode](PolicyAction policyAction) {
+    didReceiveResponse(WTFMove(response), NegotiatedLegacyTLS::No, [this, protectedThis = WTFMove(protectedThis), errorCode](PolicyAction policyAction) {
         LOG(NetworkSession, "%p - NetworkDataTaskBlob::didReceiveResponse completionHandler (%u)", this, static_cast<unsigned>(policyAction));
 
         if (m_state == State::Canceling || m_state == State::Completed) {
index c70c6e9..c5a2502 100644 (file)
@@ -206,12 +206,7 @@ void NetworkLoad::didReceiveChallenge(AuthenticationChallenge&& challenge, Negot
         m_networkProcess->authenticationManager().didReceiveAuthenticationChallenge(m_task->sessionID(), m_parameters.webPageProxyID, m_parameters.topOrigin ? &m_parameters.topOrigin->data() : nullptr, challenge, negotiatedLegacyTLS, WTFMove(completionHandler));
 }
 
-void NetworkLoad::negotiatedLegacyTLS() const
-{
-    m_networkProcess->authenticationManager().negotiatedLegacyTLS(m_parameters.webPageProxyID);
-}
-
-void NetworkLoad::didReceiveResponse(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
+void NetworkLoad::didReceiveResponse(ResourceResponse&& response, NegotiatedLegacyTLS negotiatedLegacyTLS, ResponseCompletionHandler&& completionHandler)
 {
     ASSERT(RunLoop::isMain());
     ASSERT(!m_throttle);
@@ -226,16 +221,19 @@ void NetworkLoad::didReceiveResponse(ResourceResponse&& response, ResponseComple
         return;
     }
 
-    notifyDidReceiveResponse(WTFMove(response), WTFMove(completionHandler));
+    if (negotiatedLegacyTLS == NegotiatedLegacyTLS::Yes)
+        m_networkProcess->authenticationManager().negotiatedLegacyTLS(m_parameters.webPageProxyID);
+    
+    notifyDidReceiveResponse(WTFMove(response), negotiatedLegacyTLS, WTFMove(completionHandler));
 }
 
-void NetworkLoad::notifyDidReceiveResponse(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
+void NetworkLoad::notifyDidReceiveResponse(ResourceResponse&& response, NegotiatedLegacyTLS negotiatedLegacyTLS, ResponseCompletionHandler&& completionHandler)
 {
     ASSERT(RunLoop::isMain());
 
     response.setSource(ResourceResponse::Source::Network);
     if (m_parameters.needsCertificateInfo)
-        response.includeCertificateInfo();
+        response.includeCertificateInfo(negotiatedLegacyTLS == NegotiatedLegacyTLS::Yes ? UsedLegacyTLS::Yes : UsedLegacyTLS::No);
 
     m_client.get().didReceiveResponse(WTFMove(response), WTFMove(completionHandler));
 }
@@ -265,7 +263,7 @@ void NetworkLoad::throttleDelayCompleted()
 
     auto throttle = WTFMove(m_throttle);
 
-    notifyDidReceiveResponse(WTFMove(throttle->response), WTFMove(throttle->responseCompletionHandler));
+    notifyDidReceiveResponse(WTFMove(throttle->response), NegotiatedLegacyTLS::No, WTFMove(throttle->responseCompletionHandler));
 }
 
 void NetworkLoad::didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend)
index 2411c31..2392ea5 100644 (file)
@@ -74,16 +74,15 @@ private:
     // NetworkDataTaskClient
     void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&) final;
     void didReceiveChallenge(WebCore::AuthenticationChallenge&&, NegotiatedLegacyTLS, ChallengeCompletionHandler&&) final;
-    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
+    void didReceiveResponse(WebCore::ResourceResponse&&, NegotiatedLegacyTLS, ResponseCompletionHandler&&) final;
     void didReceiveData(Ref<WebCore::SharedBuffer>&&) final;
     void didCompleteWithError(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&) final;
     void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend) final;
     void wasBlocked() final;
     void cannotShowURL() final;
     void wasBlockedByRestrictions() final;
-    void negotiatedLegacyTLS() const final;
 
-    void notifyDidReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&);
+    void notifyDidReceiveResponse(WebCore::ResourceResponse&&, NegotiatedLegacyTLS, ResponseCompletionHandler&&);
     void throttleDelayCompleted();
 
     std::reference_wrapper<NetworkLoadClient> m_client;
index 151b48c..e23de93 100644 (file)
@@ -55,6 +55,8 @@ class NetworkLoadChecker;
 class ServiceWorkerFetchTask;
 class WebSWServerConnection;
 
+enum class NegotiatedLegacyTLS : bool;
+
 struct ResourceLoadInfo;
 
 namespace NetworkCache {
index b713fff..e54a887 100644 (file)
@@ -160,7 +160,7 @@ void PingLoad::didReceiveChallenge(AuthenticationChallenge&& challenge, Negotiat
     didFinish(ResourceError { String(), 0, currentURL(), "Failed HTTP authentication"_s, ResourceError::Type::AccessControl });
 }
 
-void PingLoad::didReceiveResponse(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
+void PingLoad::didReceiveResponse(ResourceResponse&& response, NegotiatedLegacyTLS, ResponseCompletionHandler&& completionHandler)
 {
     RELEASE_LOG_IF_ALLOWED("didReceiveResponse - httpStatusCode: %d", response.httpStatusCode());
     auto weakThis = makeWeakPtr(*this);
index 7cd1052..19ec8ce 100644 (file)
@@ -53,7 +53,7 @@ private:
 
     void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&) final;
     void didReceiveChallenge(WebCore::AuthenticationChallenge&&, NegotiatedLegacyTLS, ChallengeCompletionHandler&&) final;
-    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
+    void didReceiveResponse(WebCore::ResourceResponse&&, NegotiatedLegacyTLS, ResponseCompletionHandler&&) final;
     void didReceiveData(Ref<WebCore::SharedBuffer>&&) final;
     void didCompleteWithError(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&) final;
     void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend) final;
index 8c54e22..43d8e0e 100644 (file)
@@ -107,7 +107,7 @@ public:
     size_t approximateSize() const;
 
     // Incrementing this number will delete all existing cache content for everyone. Do you really need to do it?
-    static const unsigned version = 15;
+    static const unsigned version = 16;
 
     String basePathIsolatedCopy() const;
     String versionPath() const;
index cc41514..02b1d30 100644 (file)
@@ -54,7 +54,7 @@ public:
     void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend);
     void didReceiveChallenge(WebCore::AuthenticationChallenge&&, NegotiatedLegacyTLS, ChallengeCompletionHandler&&);
     void didCompleteWithError(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&);
-    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&);
+    void didReceiveResponse(WebCore::ResourceResponse&&, NegotiatedLegacyTLS, ResponseCompletionHandler&&);
     void didReceiveData(Ref<WebCore::SharedBuffer>&&);
 
     void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&);
index f8ade92..12d3961 100644 (file)
@@ -373,10 +373,10 @@ void NetworkDataTaskCocoa::didReceiveData(Ref<WebCore::SharedBuffer>&& data)
         m_client->didReceiveData(WTFMove(data));
 }
 
-void NetworkDataTaskCocoa::didReceiveResponse(WebCore::ResourceResponse&& response, WebKit::ResponseCompletionHandler&& completionHandler)
+void NetworkDataTaskCocoa::didReceiveResponse(WebCore::ResourceResponse&& response, NegotiatedLegacyTLS negotiatedLegacyTLS, WebKit::ResponseCompletionHandler&& completionHandler)
 {
     EMIT_SIGNPOST(m_task, "received response headers");
-    NetworkDataTask::didReceiveResponse(WTFMove(response), WTFMove(completionHandler));
+    NetworkDataTask::didReceiveResponse(WTFMove(response), negotiatedLegacyTLS, WTFMove(completionHandler));
 }
 
 void NetworkDataTaskCocoa::willPerformHTTPRedirection(WebCore::ResourceResponse&& redirectResponse, WebCore::ResourceRequest&& request, RedirectCompletionHandler&& completionHandler)
index 8ca5209..2a35924 100644 (file)
@@ -818,24 +818,22 @@ static inline void processServerTrustEvaluation(NetworkSessionCocoa& session, Se
     if (auto* networkDataTask = [self existingTask:dataTask]) {
         ASSERT(RunLoop::isMain());
 
-        bool negotiatedLegacyTLS = false;
+        NegotiatedLegacyTLS negotiatedLegacyTLS = NegotiatedLegacyTLS::No;
 #if HAVE(TLS_PROTOCOL_VERSION_T)
         NSURLSessionTaskTransactionMetrics *metrics = dataTask._incompleteTaskMetrics.transactionMetrics.lastObject;
         auto tlsVersion = (tls_protocol_version_t)metrics.negotiatedTLSProtocolVersion.unsignedShortValue;
         if (tlsVersion == tls_protocol_version_TLSv10 || tlsVersion == tls_protocol_version_TLSv11)
-            negotiatedLegacyTLS = true;
+            negotiatedLegacyTLS = NegotiatedLegacyTLS::Yes;
         UNUSED_PARAM(metrics);
 #else // We do not need to check _TLSNegotiatedProtocolVersion if we have metrics.negotiatedTLSProtocolVersion because it works at response time even before rdar://problem/56522601
         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
         if ([dataTask respondsToSelector:@selector(_TLSNegotiatedProtocolVersion)]) {
             SSLProtocol tlsVersion = [dataTask _TLSNegotiatedProtocolVersion];
             if (tlsVersion == kTLSProtocol11 || tlsVersion == kTLSProtocol1)
-                negotiatedLegacyTLS = true;
+                negotiatedLegacyTLS = NegotiatedLegacyTLS::Yes;
         }
         ALLOW_DEPRECATED_DECLARATIONS_END
 #endif
-        if (negotiatedLegacyTLS)
-            networkDataTask->negotiatedLegacyTLS();
         
         // Avoid MIME type sniffing if the response comes back as 304 Not Modified.
         int statusCode = [response isKindOfClass:NSHTTPURLResponse.class] ? [(NSHTTPURLResponse *)response statusCode] : 0;
@@ -854,7 +852,7 @@ static inline void processServerTrustEvaluation(NetworkSessionCocoa& session, Se
         copyTimingData([dataTask _timingData], resourceResponse.deprecatedNetworkLoadMetrics());
 
         auto completionHandlerCopy = Block_copy(completionHandler);
-        networkDataTask->didReceiveResponse(WTFMove(resourceResponse), [completionHandlerCopy, taskIdentifier](WebCore::PolicyAction policyAction) {
+        networkDataTask->didReceiveResponse(WTFMove(resourceResponse), negotiatedLegacyTLS, [completionHandlerCopy, taskIdentifier](WebCore::PolicyAction policyAction) {
 #if !LOG_DISABLED
             LOG(NetworkSession, "%llu didReceiveResponse completionHandler (%d)", taskIdentifier, policyAction);
 #else
index cbac99e..ce05417 100644 (file)
@@ -224,7 +224,7 @@ bool NetworkDataTaskCurl::shouldRedirectAsGET(const ResourceRequest& request, bo
 
 void NetworkDataTaskCurl::invokeDidReceiveResponse()
 {
-    didReceiveResponse(ResourceResponse(m_response), [this, protectedThis = makeRef(*this)](PolicyAction policyAction) {
+    didReceiveResponse(ResourceResponse(m_response), NegotiatedLegacyTLS::No, [this, protectedThis = makeRef(*this)](PolicyAction policyAction) {
         if (m_state == State::Canceling || m_state == State::Completed)
             return;
 
index 6817f0d..0a844c3 100644 (file)
@@ -378,7 +378,7 @@ void NetworkDataTaskSoup::dispatchDidReceiveResponse()
     deprecatedResponseMetrics.requestStart = m_networkLoadMetrics.requestStart;
     deprecatedResponseMetrics.responseStart = m_networkLoadMetrics.responseStart;
 
-    didReceiveResponse(ResourceResponse(m_response), [this, protectedThis = makeRef(*this)](PolicyAction policyAction) {
+    didReceiveResponse(ResourceResponse(m_response), NegotiatedLegacyTLS::No, [this, protectedThis = makeRef(*this)](PolicyAction policyAction) {
         if (m_state == State::Canceling || m_state == State::Completed) {
             clearRequest();
             return;
index 5718dca..ab4a005 100644 (file)
@@ -317,7 +317,7 @@ void PageLoadState::didFailProvisionalLoad(const Transaction::Token& token)
     m_uncommittedState.unreachableURL = m_lastUnreachableURL;
 }
 
-void PageLoadState::didCommitLoad(const Transaction::Token& token, WebCertificateInfo& certificateInfo, bool hasInsecureContent)
+void PageLoadState::didCommitLoad(const Transaction::Token& token, WebCertificateInfo& certificateInfo, bool hasInsecureContent, bool usedLegacyTLS)
 {
     ASSERT_UNUSED(token, &token.m_pageLoadState == this);
     ASSERT(m_uncommittedState.state == State::Provisional);
@@ -328,7 +328,7 @@ void PageLoadState::didCommitLoad(const Transaction::Token& token, WebCertificat
 
     m_uncommittedState.url = m_uncommittedState.provisionalURL;
     m_uncommittedState.provisionalURL = String();
-    m_uncommittedState.negotiatedLegacyTLS = false;
+    m_uncommittedState.negotiatedLegacyTLS = usedLegacyTLS;
 
     m_uncommittedState.title = String();
 }
index fb787d4..8fde15f 100644 (file)
@@ -163,7 +163,7 @@ public:
     void didReceiveServerRedirectForProvisionalLoad(const Transaction::Token&, const String& url);
     void didFailProvisionalLoad(const Transaction::Token&);
 
-    void didCommitLoad(const Transaction::Token&, WebCertificateInfo&, bool hasInsecureContent);
+    void didCommitLoad(const Transaction::Token&, WebCertificateInfo&, bool hasInsecureContent, bool usedLegacyTLS);
     void didFinishLoad(const Transaction::Token&);
     void didFailLoad(const Transaction::Token&);
 
index 5fb0093..3daacd0 100644 (file)
@@ -264,7 +264,7 @@ void ProvisionalPageProxy::didFailProvisionalLoadForFrame(FrameIdentifier frameI
     m_page.didFailProvisionalLoadForFrameShared(m_process.copyRef(), frameID, WTFMove(frameSecurityOrigin), navigationID, provisionalURL, error, willContinueLoading, userData); // May delete |this|.
 }
 
-void ProvisionalPageProxy::didCommitLoadForFrame(FrameIdentifier frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo& certificateInfo, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData& userData)
+void ProvisionalPageProxy::didCommitLoadForFrame(FrameIdentifier frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo& certificateInfo, bool usedLegacyTLS, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData& userData)
 {
     if (!validateInput(frameID, navigationID))
         return;
@@ -274,7 +274,7 @@ void ProvisionalPageProxy::didCommitLoadForFrame(FrameIdentifier frameID, uint64
     m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_webPageID);
 
     m_wasCommitted = true;
-    m_page.commitProvisionalPage(frameID, navigationID, mimeType, frameHasCustomContentProvider, frameLoadType, certificateInfo, containsPluginDocument, forcedHasInsecureContent, userData); // Will delete |this|.
+    m_page.commitProvisionalPage(frameID, navigationID, mimeType, frameHasCustomContentProvider, frameLoadType, certificateInfo, usedLegacyTLS, containsPluginDocument, forcedHasInsecureContent, userData); // Will delete |this|.
 }
 
 void ProvisionalPageProxy::didNavigateWithNavigationData(const WebNavigationDataStore& store, FrameIdentifier frameID)
index b9f6574..b11de1c 100644 (file)
@@ -122,7 +122,7 @@ private:
     void didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, WebCore::FrameIdentifier);
     void didCreateMainFrame(WebCore::FrameIdentifier);
     void didStartProvisionalLoadForFrame(WebCore::FrameIdentifier, uint64_t navigationID, URL&&, URL&& unreachableURL, const UserData&);
-    void didCommitLoadForFrame(WebCore::FrameIdentifier, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&);
+    void didCommitLoadForFrame(WebCore::FrameIdentifier, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool usedLegacyTLS, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&);
     void didFailProvisionalLoadForFrame(WebCore::FrameIdentifier, WebCore::SecurityOriginData&& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError&, WebCore::WillContinueLoading, const UserData&);
     void startURLSchemeTask(URLSchemeTaskParameters&&);
     void backForwardGoToItem(const WebCore::BackForwardItemIdentifier&, CompletionHandler<void(SandboxExtension::Handle&&, const WebBackForwardListCounts&)>&&);
index bcd9a25..d601e50 100644 (file)
@@ -3161,7 +3161,7 @@ void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation*
     sender->send(action, navigation ? navigation->navigationID() : 0, downloadID, WTFMove(websitePolicies));
 }
 
-void WebPageProxy::commitProvisionalPage(FrameIdentifier frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo& certificateInfo, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData& userData)
+void WebPageProxy::commitProvisionalPage(FrameIdentifier frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo& certificateInfo, bool usedLegacyTLS, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData& userData)
 {
     ASSERT(m_provisionalPage);
     RELEASE_LOG_IF_ALLOWED(Loading, "commitProvisionalPage: newPID = %i", m_provisionalPage->process().processIdentifier());
@@ -3195,7 +3195,7 @@ void WebPageProxy::commitProvisionalPage(FrameIdentifier frameID, uint64_t navig
     const auto oldWebPageID = m_webPageID;
     swapToProvisionalPage(std::exchange(m_provisionalPage, nullptr));
 
-    didCommitLoadForFrame(frameID, navigationID, mimeType, frameHasCustomContentProvider, frameLoadType, certificateInfo, containsPluginDocument, forcedHasInsecureContent, userData);
+    didCommitLoadForFrame(frameID, navigationID, mimeType, frameHasCustomContentProvider, frameLoadType, certificateInfo, usedLegacyTLS, containsPluginDocument, forcedHasInsecureContent, userData);
 
     m_inspectorController->didCommitProvisionalPage(oldWebPageID, m_webPageID);
 }
@@ -4481,7 +4481,7 @@ static OptionSet<CrossSiteNavigationDataTransfer::Flag> checkIfNavigationContain
 }
 #endif
 
-void WebPageProxy::didCommitLoadForFrame(FrameIdentifier frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, bool containsPluginDocument, Optional<HasInsecureContent> hasInsecureContent, const UserData& userData)
+void WebPageProxy::didCommitLoadForFrame(FrameIdentifier frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, bool usedLegacyTLS, bool containsPluginDocument, Optional<HasInsecureContent> hasInsecureContent, const UserData& userData)
 {
     LOG(Loading, "(Loading) WebPageProxy %" PRIu64 " didCommitLoadForFrame in navigation %" PRIu64, m_identifier.toUInt64(), navigationID);
     LOG(BackForward, "(Back/Forward) After load commit, back/forward list is now:%s", m_backForwardList->loggingString());
@@ -4523,7 +4523,7 @@ void WebPageProxy::didCommitLoadForFrame(FrameIdentifier frameID, uint64_t navig
     bool markPageInsecure = hasInsecureContent ? hasInsecureContent.value() == HasInsecureContent::Yes : m_treatsSHA1CertificatesAsInsecure && certificateInfo.containsNonRootSHA1SignedCertificate();
 
     if (frame->isMainFrame()) {
-        m_pageLoadState.didCommitLoad(transaction, webCertificateInfo, markPageInsecure);
+        m_pageLoadState.didCommitLoad(transaction, webCertificateInfo, markPageInsecure, usedLegacyTLS);
         m_shouldSuppressNextAutomaticNavigationSnapshot = false;
     } else if (markPageInsecure)
         m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
index 025233f..4807106 100644 (file)
@@ -1587,7 +1587,7 @@ public:
 #endif
 
     ProvisionalPageProxy* provisionalPageProxy() const { return m_provisionalPage.get(); }
-    void commitProvisionalPage(WebCore::FrameIdentifier, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&);
+    void commitProvisionalPage(WebCore::FrameIdentifier, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool usedLegacyTLS, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&);
 
     // Logic shared between the WebPageProxy and the ProvisionalPageProxy.
     void didStartProvisionalLoadForFrameShared(Ref<WebProcessProxy>&&, WebCore::FrameIdentifier, uint64_t navigationID, URL&&, URL&& unreachableURL, const UserData&);
@@ -1737,7 +1737,7 @@ private:
     void didCancelClientRedirectForFrame(WebCore::FrameIdentifier);
     void didChangeProvisionalURLForFrame(WebCore::FrameIdentifier, uint64_t navigationID, URL&&);
     void didFailProvisionalLoadForFrame(WebCore::FrameIdentifier, WebCore::SecurityOriginData&& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError&, WebCore::WillContinueLoading, const UserData&);
-    void didCommitLoadForFrame(WebCore::FrameIdentifier, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&);
+    void didCommitLoadForFrame(WebCore::FrameIdentifier, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool usedLegacyTLS, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&);
     void didFinishDocumentLoadForFrame(WebCore::FrameIdentifier, uint64_t navigationID, const UserData&);
     void didFinishLoadForFrame(WebCore::FrameIdentifier, uint64_t navigationID, const UserData&);
     void didFailLoadForFrame(WebCore::FrameIdentifier, uint64_t navigationID, const WebCore::ResourceError&, const UserData&);
index a6d4c61..14bed1b 100644 (file)
@@ -126,7 +126,7 @@ messages -> WebPageProxy {
     DidCancelClientRedirectForFrame(WebCore::FrameIdentifier frameID)
     DidChangeProvisionalURLForFrame(WebCore::FrameIdentifier frameID, uint64_t navigationID, URL url)
     DidFailProvisionalLoadForFrame(WebCore::FrameIdentifier frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, String provisionalURL, WebCore::ResourceError error, enum:bool WebCore::WillContinueLoading willContinueLoading, WebKit::UserData userData)
-    DidCommitLoadForFrame(WebCore::FrameIdentifier frameID, uint64_t navigationID, String mimeType, bool hasCustomContentProvider, uint32_t loadType, WebCore::CertificateInfo certificateInfo, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, WebKit::UserData userData)
+    DidCommitLoadForFrame(WebCore::FrameIdentifier frameID, uint64_t navigationID, String mimeType, bool hasCustomContentProvider, uint32_t loadType, WebCore::CertificateInfo certificateInfo, bool usedLegacyTLS, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, WebKit::UserData userData)
     DidFailLoadForFrame(WebCore::FrameIdentifier frameID, uint64_t navigationID, WebCore::ResourceError error, WebKit::UserData userData)
     DidFinishDocumentLoadForFrame(WebCore::FrameIdentifier frameID, uint64_t navigationID, WebKit::UserData userData)
     DidFinishLoadForFrame(WebCore::FrameIdentifier frameID, uint64_t navigationID, WebKit::UserData userData)
index 62ff60a..e087b0c 100644 (file)
@@ -560,7 +560,7 @@ void WebFrameLoaderClient::dispatchDidCommitLoad(Optional<HasInsecureContent> ha
     webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame);
 
     // Notify the UIProcess.
-    webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.response().mimeType(), m_frameHasCustomContentProvider, static_cast<uint32_t>(m_frame->coreFrame()->loader().loadType()), valueOrCompute(documentLoader.response().certificateInfo(), [] { return CertificateInfo(); }), m_frame->coreFrame()->document()->isPluginDocument(), hasInsecureContent, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
+    webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.response().mimeType(), m_frameHasCustomContentProvider, static_cast<uint32_t>(m_frame->coreFrame()->loader().loadType()), valueOrCompute(documentLoader.response().certificateInfo(), [] { return CertificateInfo(); }), documentLoader.response().usedLegacyTLS(), m_frame->coreFrame()->document()->isPluginDocument(), hasInsecureContent, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
     webPage->didCommitLoad(m_frame);
 }
 
index bd4b16a..3264703 100644 (file)
@@ -1,3 +1,24 @@
+2020-02-05  Alex Christensen  <achristensen@webkit.org>
+
+        Make WKWebView._negotiatedLegacyTLS accurate when loading main resouorce from network or cache
+        https://bugs.webkit.org/show_bug.cgi?id=207207
+
+        Reviewed by Chris Dumez.
+
+        HTTPServer now supports HTTPS. Tell your friends!
+
+        * TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm:
+        (testCertificate):
+        (testIdentity):
+        (credentialWithIdentity):
+        * TestWebKitAPI/Tests/WebKitCocoa/TLSDeprecation.mm:
+        (TestWebKitAPI::webViewWithNavigationDelegate):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/cocoa/HTTPServer.h:
+        * TestWebKitAPI/cocoa/HTTPServer.mm:
+        (TestWebKitAPI::HTTPServer::HTTPServer):
+        (TestWebKitAPI::HTTPServer::request const):
+
 2020-02-05  Brady Eidson  <beidson@apple.com>
 
         _WKDownload should expose the originating FrameInfo.
index e637bb4..9acd174 100644 (file)
@@ -25,6 +25,7 @@
 
 #import "config.h"
 
+#import "HTTPServer.h"
 #import "PlatformUtilities.h"
 #import "TCPServer.h"
 #import "Test.h"
 
 static bool navigationFinished;
 
-static RetainPtr<NSURLCredential> credentialWithIdentity()
+static RetainPtr<SecCertificateRef> testCertificate()
 {
     auto certificateBytes = TestWebKitAPI::TCPServer::testCertificate();
-    auto certificate = adoptCF(SecCertificateCreateWithData(nullptr, (__bridge CFDataRef)[NSData dataWithBytes:certificateBytes.data() length:certificateBytes.size()]));
-    
+    return adoptCF(SecCertificateCreateWithData(nullptr, (__bridge CFDataRef)[NSData dataWithBytes:certificateBytes.data() length:certificateBytes.size()]));
+}
+
+RetainPtr<SecIdentityRef> testIdentity()
+{
     auto privateKeyBytes = TestWebKitAPI::TCPServer::testPrivateKey();
     NSData *derEncodedPrivateKey = [NSData dataWithBytes:privateKeyBytes.data() length:privateKeyBytes.size()];
     NSDictionary* options = @{
@@ -61,10 +65,15 @@ static RetainPtr<NSURLCredential> credentialWithIdentity()
     EXPECT_NULL(error);
     EXPECT_NOT_NULL(privateKey.get());
 
-    auto identity = adoptCF(SecIdentityCreate(kCFAllocatorDefault, certificate.get(), privateKey.get()));
+    return adoptCF(SecIdentityCreate(kCFAllocatorDefault, testCertificate().get(), privateKey.get()));
+}
+
+static RetainPtr<NSURLCredential> credentialWithIdentity()
+{
+    auto identity = testIdentity();
     EXPECT_NOT_NULL(identity);
     
-    return [NSURLCredential credentialWithIdentity:identity.get() certificates:@[(id)certificate.get()] persistence:NSURLCredentialPersistenceNone];
+    return [NSURLCredential credentialWithIdentity:identity.get() certificates:@[(id)testCertificate().get()] persistence:NSURLCredentialPersistenceNone];
 }
 
 @interface ChallengeDelegate : NSObject <WKNavigationDelegate>
index 3f7c07e..6cabec0 100644 (file)
@@ -27,6 +27,7 @@
 
 #if HAVE(SSL)
 
+#import "HTTPServer.h"
 #import "PlatformUtilities.h"
 #import "TCPServer.h"
 #import "TestNavigationDelegate.h"
 #import <WebKit/WebKit.h>
 #import <WebKit/_WKWebsiteDataStoreConfiguration.h>
 #import <wtf/RetainPtr.h>
+#import <wtf/text/StringConcatenateNumbers.h>
 
 #if PLATFORM(IOS_FAMILY)
 #import <WebKit/WebUIKitSupport.h>
 #import <WebKit/WebCoreThread.h>
 #endif
 
-#if HAVE(TLS_PROTOCOL_VERSION_T)
+#if HAVE(TLS_PROTOCOL_VERSION_T) || HAVE(NETWORK_FRAMEWORK)
 @interface TLSObserver : NSObject
 - (void)waitUntilNegotiatedLegacyTLSChanged;
 @end
@@ -228,13 +230,9 @@ TEST(TLSVersion, DISABLED_NavigationDelegateSPI)
 }
 
 #if HAVE(TLS_PROTOCOL_VERSION_T)
-TEST(TLSVersion, NegotiatedLegacyTLS)
-{
-    TCPServer server(TCPServer::Protocol::HTTPS, [] (SSL *ssl) {
-        TCPServer::respondWithOK(ssl);
-        TCPServer::respondWithOK(ssl);
-    }, tls1_1);
 
+static std::pair<RetainPtr<WKWebView>, RetainPtr<TestNavigationDelegate>> webViewWithNavigationDelegate()
+{
     auto delegate = adoptNS([TestNavigationDelegate new]);
     auto webView = adoptNS([WKWebView new]);
     [webView setNavigationDelegate:delegate.get()];
@@ -242,6 +240,20 @@ TEST(TLSVersion, NegotiatedLegacyTLS)
         EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
         callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
     }];
+    return { webView, delegate };
+}
+
+#endif // HAVE(TLS_PROTOCOL_VERSION_T) || HAVE(NETWORK_FRAMEWORK)
+
+#if HAVE(TLS_PROTOCOL_VERSION_T)
+
+TEST(TLSVersion, NegotiatedLegacyTLS)
+{
+    HTTPServer server({
+        { "/", { "hello" } }
+    }, HTTPServer::Protocol::HttpsWithLegacyTLS);
+
+    auto [webView, delegate] = webViewWithNavigationDelegate();
     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]];
     [webView loadRequest:request];
 
@@ -262,7 +274,64 @@ TEST(TLSVersion, NegotiatedLegacyTLS)
 
     [webView removeObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS"];
 }
-#endif
+
+#endif // HAVE(TLS_PROTOCOL_VERSION_T)
+
+#if HAVE(NETWORK_FRAMEWORK) && HAVE(TLS_PROTOCOL_VERSION_T)
+
+TEST(TLSVersion, NavigateBack)
+{
+    HTTPServer legacyTLSServer({
+        { "/", { "hello" } }
+    }, HTTPServer::Protocol::HttpsWithLegacyTLS);
+
+    HTTPServer modernTLSServer({
+        { "/", { "hello" } }
+    }, HTTPServer::Protocol::Https);
+    
+    auto [webView, delegate] = webViewWithNavigationDelegate();
+    auto observer = adoptNS([TLSObserver new]);
+    [webView addObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS" options:NSKeyValueObservingOptionNew context:nil];
+
+    [webView loadRequest:legacyTLSServer.request()];
+    EXPECT_FALSE([webView _negotiatedLegacyTLS]);
+    [delegate waitForDidFinishNavigation];
+    EXPECT_TRUE([webView _negotiatedLegacyTLS]);
+
+    [webView loadRequest:modernTLSServer.request()];
+    [delegate waitForDidFinishNavigation];
+    EXPECT_FALSE([webView _negotiatedLegacyTLS]);
+
+    [webView goBack];
+    [observer waitUntilNegotiatedLegacyTLSChanged];
+    EXPECT_TRUE([webView _negotiatedLegacyTLS]);
+
+    [webView removeObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS"];
+}
+
+TEST(TLSVersion, Subresource)
+{
+    HTTPServer legacyTLSServer({
+        { "/", { "hello" } }
+    }, HTTPServer::Protocol::HttpsWithLegacyTLS);
+
+    HTTPServer modernTLSServer({
+        { "/", { makeString("<script>fetch('https://127.0.0.1:", static_cast<unsigned>(legacyTLSServer.port()), "/',{mode:'no-cors'})</script>") } }
+    }, HTTPServer::Protocol::Https);
+    
+    auto [webView, delegate] = webViewWithNavigationDelegate();
+    auto observer = adoptNS([TLSObserver new]);
+    [webView addObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS" options:NSKeyValueObservingOptionNew context:nil];
+
+    EXPECT_FALSE([webView _negotiatedLegacyTLS]);
+    [webView loadRequest:modernTLSServer.request()];
+    while (![webView _negotiatedLegacyTLS])
+        [observer waitUntilNegotiatedLegacyTLSChanged];
+
+    [webView removeObserver:observer.get() forKeyPath:@"_negotiatedLegacyTLS"];
+}
+
+#endif // HAVE(NETWORK_FRAMEWORK) && HAVE(TLS_PROTOCOL_VERSION_T)
 
 // FIXME: Add some tests for WKWebView.hasOnlySecureContent
 
index 3826d17..9392e45 100644 (file)
@@ -38,7 +38,8 @@ namespace TestWebKitAPI {
 class HTTPServer {
 public:
     struct HTTPResponse;
-    HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>>);
+    enum class Protocol : uint8_t { Http, Https, HttpsWithLegacyTLS };
+    HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>>, Protocol = Protocol::Http);
     uint16_t port() const;
     NSURLRequest *request() const;
     
@@ -46,6 +47,7 @@ private:
     void respondToRequests(nw_connection_t);
     
     RetainPtr<nw_listener_t> m_listener;
+    const Protocol m_protocol;
     const HashMap<String, HTTPResponse> m_requestResponseMap;
 };
 
@@ -74,3 +76,5 @@ struct HTTPServer::HTTPResponse {
 } // namespace TestWebKitAPI
 
 #endif // HAVE(NETWORK_FRAMEWORK)
+
+RetainPtr<SecIdentityRef> testIdentity();
index 0f4b03e..a2cc69c 100644 (file)
 
 namespace TestWebKitAPI {
 
-HTTPServer::HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>> responses)
-    : m_requestResponseMap([](std::initializer_list<std::pair<String, HTTPServer::HTTPResponse>> list) {
+HTTPServer::HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>> responses, Protocol protocol)
+    : m_protocol(protocol)
+    , m_requestResponseMap([](std::initializer_list<std::pair<String, HTTPServer::HTTPResponse>> list) {
         HashMap<String, HTTPServer::HTTPResponse> map;
         for (auto& pair : list)
             map.add(pair.first, pair.second);
         return map;
     }(responses))
 {
-    auto parameters = adoptNS(nw_parameters_create_secure_tcp(NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION));
+    auto configureTLS = protocol == Protocol::Http ? NW_PARAMETERS_DISABLE_PROTOCOL : ^(nw_protocol_options_t protocolOptions) {
+#if HAVE(TLS_PROTOCOL_VERSION_T)
+        auto options = adoptNS(nw_tls_copy_sec_protocol_options(protocolOptions));
+        auto identity = adoptNS(sec_identity_create(testIdentity().get()));
+        sec_protocol_options_set_local_identity(options.get(), identity.get());
+        if (protocol == Protocol::HttpsWithLegacyTLS)
+            sec_protocol_options_set_max_tls_protocol_version(options.get(), tls_protocol_version_TLSv10);
+#else
+        UNUSED_PARAM(protocolOptions);
+        ASSERT(protocol != Protocol::HttpsWithLegacyTLS);
+#endif
+    };
+    auto parameters = adoptNS(nw_parameters_create_secure_tcp(configureTLS, NW_PARAMETERS_DEFAULT_CONFIGURATION));
     m_listener = adoptNS(nw_listener_create(parameters.get()));
     nw_listener_set_queue(m_listener.get(), dispatch_get_main_queue());
     nw_listener_set_new_connection_handler(m_listener.get(), ^(nw_connection_t connection) {
@@ -135,7 +148,17 @@ uint16_t HTTPServer::port() const
 
 NSURLRequest *HTTPServer::request() const
 {
-    return [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", port()]]];
+    NSString *format;
+    switch (m_protocol) {
+    case Protocol::Http:
+        format = @"http://127.0.0.1:%d/";
+        break;
+    case Protocol::Https:
+    case Protocol::HttpsWithLegacyTLS:
+        format = @"https://127.0.0.1:%d/";
+        break;
+    }
+    return [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:format, port()]]];
 }
 
 } // namespace TestWebKitAPI