Remove access to keychain from the WebContent process
authorjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Apr 2018 22:10:01 +0000 (22:10 +0000)
committerjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Apr 2018 22:10:01 +0000 (22:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184428
<rdar://problem/13150903>

Reviewed by Brent Fulgham.

Source/WebCore:

Part 2.

This patch move the operation of HTMLKeygenElement from WebContent Process to UI Process.
Function signedPublicKeyAndChallengeString is therefore marked as WEBCORE_EXPORT. Also, a
localized string is marked WEBCORE_EXPORT as well to support the API test.

Covered by existing tests and api tests.

* WebCore.xcodeproj/project.pbxproj:
* dom/Document.cpp:
(WebCore::Document::signedPublicKeyAndChallengeString):
* dom/Document.h:
* html/HTMLKeygenElement.cpp:
(WebCore::HTMLKeygenElement::appendFormData):
* page/ChromeClient.h:
* platform/LocalizedStrings.h:
* platform/SSLKeyGenerator.h:

Source/WebKit:

This patch does the followings:
1. Added necessary support to move HTMLKeygenElement's operation from WebContent Process to UI Process.
2. Craft new SPI copySignedPublicKeyAndChallengeString to supply HTMLKeygenElement with dummy data such
that WebKitTestRunner tests will not modify the underlying key store (e.g., the macOS Keychain).

* UIProcess/API/APINavigationClient.h:
(API::NavigationClient::signedPublicKeyAndChallengeString):
* UIProcess/API/C/WKPage.cpp:
(WKPageSetPageNavigationClient):
* UIProcess/API/C/WKPageNavigationClient.h:
* UIProcess/Cocoa/NavigationState.h:
* UIProcess/Cocoa/NavigationState.mm:
(WebKit::NavigationState::NavigationClient::signedPublicKeyAndChallengeString):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::signedPublicKeyAndChallengeString):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::signedPublicKeyAndChallengeString const):
* WebProcess/WebCoreSupport/WebChromeClient.h:

Source/WebKitLegacy/mac:

This patch does the followings:
1. Added necessary support to move HTMLKeygenElement's operation from WebCore space to Client space.
2. Craft new SPI signedPublicKeyAndChallengeStringForWebView to supply HTMLKeygenElement with dummy data
such that DumpRenderTree tests will not modify the underlying key store (e.g., the macOS Keychain).

* WebCoreSupport/WebChromeClient.h:
* WebCoreSupport/WebChromeClient.mm:
(WebChromeClient::signedPublicKeyAndChallengeString const):
* WebView/WebUIDelegatePrivate.h:

Tools:

This patch does the followings:
1. Added an API test for this patch.
2. Instrument DumpRenderTree and WebKitTestRunner to take advantages of new SPIs.

* DumpRenderTree/mac/UIDelegate.mm:
(-[UIDelegate signedPublicKeyAndChallengeStringForWebView:]):
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/mac/SSLKeyGenerator.mm: Added.
(TestWebKitAPI::SSLKeyGeneratorTest::SetUp):
(TestWebKitAPI::SSLKeyGeneratorTest::TearDown):
(TestWebKitAPI::TEST_F):
* WebKitTestRunner/TestController.cpp:
(WTR::copySignedPublicKeyAndChallengeString):
(WTR::TestController::createOtherPage):
(WTR::TestController::createWebViewWithOptions):

LayoutTests:

Alter the layout test to match dummy data supplied by the test runners.
Modify expectations as well.

* http/tests/misc/resources/check-keygen-post.php:
* platform/gtk/TestExpectations:
* platform/ios/TestExpectations:
* platform/mac/TestExpectations:

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

33 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/misc/resources/check-keygen-post.php
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/ios/TestExpectations
LayoutTests/platform/mac/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/html/HTMLKeygenElement.cpp
Source/WebCore/page/ChromeClient.h
Source/WebCore/platform/LocalizedStrings.h
Source/WebCore/platform/SSLKeyGenerator.h
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/APINavigationClient.h
Source/WebKit/UIProcess/API/C/WKPage.cpp
Source/WebKit/UIProcess/API/C/WKPageNavigationClient.h
Source/WebKit/UIProcess/Cocoa/NavigationState.h
Source/WebKit/UIProcess/Cocoa/NavigationState.mm
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h
Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm
Source/WebKitLegacy/mac/WebView/WebUIDelegatePrivate.h
Tools/ChangeLog
Tools/DumpRenderTree/mac/UIDelegate.mm
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/mac/SSLKeyGenerator.mm [new file with mode: 0644]
Tools/WebKitTestRunner/TestController.cpp

index ca85104..08f51c9 100644 (file)
@@ -1,3 +1,19 @@
+2018-04-25  Jiewen Tan  <jiewen_tan@apple.com>
+
+        Remove access to keychain from the WebContent process
+        https://bugs.webkit.org/show_bug.cgi?id=184428
+        <rdar://problem/13150903>
+
+        Reviewed by Brent Fulgham.
+
+        Alter the layout test to match dummy data supplied by the test runners.
+        Modify expectations as well.
+
+        * http/tests/misc/resources/check-keygen-post.php:
+        * platform/gtk/TestExpectations:
+        * platform/ios/TestExpectations:
+        * platform/mac/TestExpectations:
+
 2018-04-25  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [Extra zoom mode] The search field on www.bing.com is missing label text
index e185a96..fe731ba 100644 (file)
@@ -9,7 +9,7 @@ function runTest()
 {
     var r = document.getElementById('result');
     var o = document.getElementById('output').firstChild;
-    if (o.nodeValue == 'spkac exists') 
+    if (o.nodeValue == 'MIHFMHEwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAnX0TILJrOMUue%2BPtwBRE6XfV%0AWtKQbsshxk5ZhcUwcwyvcnIq9b82QhJdoACdD34rqfCAIND46fXKQUnb0mvKzQID%0AAQABFhFNb3ppbGxhSXNNeUZyaWVuZDANBgkqhkiG9w0BAQQFAANBAAKv2Eex2n%2FS%0Ar%2F7iJNroWlSzSMtTiQTEB%2BADWHGj9u1xrUrOilq%2Fo2cuQxIfZcNZkYAkWP4DubqW%0Ai0%2F%2FrgBvmco%3D')
         r.innerHTML = "SUCCESS: keygen was parsed correctly";
     else
         r.innerHTML = "FAILURE: keygen was not parsed correctly. value=" +
@@ -27,7 +27,7 @@ This is a regression test for keygen tag POST processing: https://bugs.webkit.or
 </p>
 <div style='display: none;' id='output'><?php
 if (array_key_exists('spkac', $_REQUEST)) {
-    echo "spkac exists";
+    echo $_REQUEST['spkac'];
 } else {
     echo "spkac does not exist";
 }
index 15da595..98f3305 100644 (file)
@@ -2531,9 +2531,6 @@ webkit.org/b/100238 fast/history/window-open.html [ Failure ]
 webkit.org/b/53964 fast/forms/listbox-onchange.html [ Failure ]
 webkit.org/b/53964 fast/forms/option-mouseevents.html [ Failure ]
 
-# keygen element rendering is broken
-webkit.org/b/54136 http/tests/misc/submit-post-keygen.html [ Failure ]
-
 webkit.org/b/122021 media/video-controls-captions-trackmenu.html [ Failure ]
 webkit.org/b/123097 media/track/track-user-preferences.html [ Skip ]
 webkit.org/b/121995 media/video-controls-captions-trackmenu-includes-enabled-track.html [ Failure ]
index 1683ca3..0d1e507 100644 (file)
@@ -1180,7 +1180,6 @@ http/tests/local/link-stylesheet-load-order.html [ Failure ]
 http/tests/misc/favicon-loads-with-icon-loading-override.html [ Failure ]
 http/tests/misc/link-rel-icon-beforeload.html [ Failure ]
 http/tests/misc/object-embedding-svg-delayed-size-negotiation.xhtml [ Failure ]
-http/tests/misc/submit-post-keygen.html [ Failure ]
 http/tests/misc/willCacheResponse-delegate-callback.html [ Failure ]
 http/tests/navigation/response204.html [ Failure ]
 http/tests/security/contentSecurityPolicy/object-src-no-url-blocked.html [ Failure ]
index 5ed9d00..561fa6b 100644 (file)
@@ -599,9 +599,6 @@ webkit.org/b/112176 fast/css/sticky/inline-sticky.html [ ImageOnlyFailure Pass ]
 webkit.org/b/112176 fast/css/sticky/sticky-both-sides.html [ ImageOnlyFailure Pass ]
 # Once the bug 112176 is fixed, potentially restore the following test expectations.
 
-# Always very slow, frequently timing out (only on bots, not locally).
-webkit.org/b/121331 [ Sierra ] http/tests/misc/submit-post-keygen.html [ Pass Timeout ]
-
 # isProtocolHandlerRegistered() isn't supported yet.
 webkit.org/b/92749 fast/dom/NavigatorContentUtils/is-protocol-handler-registered.html [ Skip ]
 
index bd45321..8c1a9f5 100644 (file)
@@ -1,3 +1,29 @@
+2018-04-25  Jiewen Tan  <jiewen_tan@apple.com>
+
+        Remove access to keychain from the WebContent process
+        https://bugs.webkit.org/show_bug.cgi?id=184428
+        <rdar://problem/13150903>
+
+        Reviewed by Brent Fulgham.
+
+        Part 2.
+
+        This patch move the operation of HTMLKeygenElement from WebContent Process to UI Process.
+        Function signedPublicKeyAndChallengeString is therefore marked as WEBCORE_EXPORT. Also, a
+        localized string is marked WEBCORE_EXPORT as well to support the API test.
+
+        Covered by existing tests and api tests.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/Document.cpp:
+        (WebCore::Document::signedPublicKeyAndChallengeString):
+        * dom/Document.h:
+        * html/HTMLKeygenElement.cpp:
+        (WebCore::HTMLKeygenElement::appendFormData):
+        * page/ChromeClient.h:
+        * platform/LocalizedStrings.h:
+        * platform/SSLKeyGenerator.h:
+
 2018-04-25  Ryosuke Niwa  <rniwa@webkit.org>
 
         PSON: Don't create a new process when navigating to a blob URL, data URL, and about:blank
index e249c5e..7a312e6 100644 (file)
                93F1991808245E59001E9ABC /* Range.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D30402DE4476018635CA /* Range.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93F1992F08245E59001E9ABC /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = F587868402DE3B8601EA4122 /* Cursor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93F1995008245E59001E9ABC /* CachePolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = F587864902DE3A9A01EA4122 /* CachePolicy.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               93F1996308245E59001E9ABC /* SSLKeyGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = F587866202DE3B1101EA4122 /* SSLKeyGenerator.h */; };
+               93F1996308245E59001E9ABC /* SSLKeyGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = F587866202DE3B1101EA4122 /* SSLKeyGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93F1998C08245E59001E9ABC /* RenderTreeAsText.h in Headers */ = {isa = PBXBuildFile; fileRef = 93955A4103D72932008635CE /* RenderTreeAsText.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93F199A808245E59001E9ABC /* WebCoreFrameView.h in Headers */ = {isa = PBXBuildFile; fileRef = F587854C02DE375901EA4122 /* WebCoreFrameView.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93F199B808245E59001E9ABC /* Scrollbar.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7B2AF80450824100A8000F /* Scrollbar.h */; settings = {ATTRIBUTES = (Private, ); }; };
index 1d58572..08d6f5a 100644 (file)
@@ -7795,4 +7795,12 @@ void Document::setServiceWorkerConnection(SWClientConnection* serviceWorkerConne
 }
 #endif
 
+String Document::signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const URL& url)
+{
+    Page* page = this->page();
+    if (!page)
+        return emptyString();
+    return page->chrome().client().signedPublicKeyAndChallengeString(keySizeIndex, challengeString, url);
+}
+
 } // namespace WebCore
index 4b62486..4381d9b 100644 (file)
@@ -1429,6 +1429,8 @@ public:
     void setHasRequestedPageSpecificStorageAccessWithUserInteraction(const String& primaryDomain);
 #endif
 
+    String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const URL&);
+
 protected:
     enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };
     Document(Frame*, const URL&, unsigned = DefaultDocumentClass, unsigned constructionFlags = 0);
index cdd53ed..60ac275 100644 (file)
@@ -124,7 +124,7 @@ bool HTMLKeygenElement::appendFormData(DOMFormData& formData, bool)
     // Only RSA is supported at this time.
     if (!isKeytypeRSA())
         return false;
-    auto value = signedPublicKeyAndChallengeString(shadowSelect()->selectedIndex(), attributeWithoutSynchronization(challengeAttr), document().baseURL());
+    auto value = document().signedPublicKeyAndChallengeString(shadowSelect()->selectedIndex(), attributeWithoutSynchronization(challengeAttr), document().baseURL());
     if (value.isNull())
         return false;
     formData.append(name(), value);
index 4b5357f..98fa592 100644 (file)
@@ -475,6 +475,8 @@ public:
 
     virtual void testIncomingSyncIPCMessageWhileWaitingForSyncReply() { }
 
+    virtual String signedPublicKeyAndChallengeString(unsigned, const String&, const URL&) const { return emptyString(); }
+
 protected:
     virtual ~ChromeClient() = default;
 };
index 129c0f1..2d46a03 100644 (file)
@@ -238,7 +238,7 @@ namespace WebCore {
     WEBCORE_EXPORT String pdfDocumentTypeDescription();
     WEBCORE_EXPORT String postScriptDocumentTypeDescription();
     String keygenMenuItem2048();
-    String keygenKeychainItemName(const String& host);
+    WEBCORE_EXPORT String keygenKeychainItemName(const String& host);
 #endif
 
 #if PLATFORM(IOS)
index e7d6c88..0767238 100644 (file)
 
 namespace WebCore {
 
-    class URL;
+class URL;
 
-    // Returns strings representing key sizes that may be used
-    // for the <keygen> tag. The first string is displayed as the default
-    // key size in the <keygen> menu.
-    void getSupportedKeySizes(Vector<String>& sizes);
+// Returns strings representing key sizes that may be used
+// for the <keygen> tag. The first string is displayed as the default
+// key size in the <keygen> menu.
+void getSupportedKeySizes(Vector<String>& sizes);
 
-    // This function handles the <keygen> tag in form elements.
-    // Returns a signed copy of the combined challenge string and public
-    // key (from a newly generated key pair).
-    String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const URL&);
+// This function handles the <keygen> tag in form elements.
+// Returns a signed copy of the combined challenge string and public
+// key (from a newly generated key pair).
+WEBCORE_EXPORT String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const URL&);
 
 } // namespace WebCore
 
index 124c673..6f727d8 100644 (file)
@@ -1,3 +1,32 @@
+2018-04-25  Jiewen Tan  <jiewen_tan@apple.com>
+
+        Remove access to keychain from the WebContent process
+        https://bugs.webkit.org/show_bug.cgi?id=184428
+        <rdar://problem/13150903>
+
+        Reviewed by Brent Fulgham.
+
+        This patch does the followings:
+        1. Added necessary support to move HTMLKeygenElement's operation from WebContent Process to UI Process.
+        2. Craft new SPI copySignedPublicKeyAndChallengeString to supply HTMLKeygenElement with dummy data such
+        that WebKitTestRunner tests will not modify the underlying key store (e.g., the macOS Keychain).
+
+        * UIProcess/API/APINavigationClient.h:
+        (API::NavigationClient::signedPublicKeyAndChallengeString):
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPageNavigationClient):
+        * UIProcess/API/C/WKPageNavigationClient.h:
+        * UIProcess/Cocoa/NavigationState.h:
+        * UIProcess/Cocoa/NavigationState.mm:
+        (WebKit::NavigationState::NavigationClient::signedPublicKeyAndChallengeString):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::signedPublicKeyAndChallengeString):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::signedPublicKeyAndChallengeString const):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+
 2018-04-25  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [Extra zoom mode] The search field on www.bing.com is missing label text
index 55bd34d..470f65f 100644 (file)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "APIData.h"
+#include "APIString.h"
 #include "PluginModuleInfo.h"
 #include "ProcessTerminationReason.h"
 #include "SameDocumentNavigationType.h"
@@ -94,6 +95,8 @@ public:
 
     virtual RefPtr<Data> webCryptoMasterKey(WebKit::WebPageProxy&) { return nullptr; }
 
+    virtual RefPtr<String> signedPublicKeyAndChallengeString(WebKit::WebPageProxy&, unsigned keySizeIndex, const RefPtr<String>& challengeString, const WebCore::URL&) { return nullptr; }
+
 #if USE(QUICK_LOOK)
     virtual void didStartLoadForQuickLookDocumentInMainFrame(const WTF::String& fileName, const WTF::String& uti) { }
     virtual void didFinishLoadForQuickLookDocumentInMainFrame(const WebKit::QuickLookDocumentData&) { }
index ba4aaba..67cfbf3 100644 (file)
@@ -72,6 +72,7 @@
 #include "WebProcessProxy.h"
 #include "WebProtectionSpace.h"
 #include <WebCore/Page.h>
+#include <WebCore/SSLKeyGenerator.h>
 #include <WebCore/SecurityOriginData.h>
 #include <WebCore/SerializedCryptoKeyWrap.h>
 #include <WebCore/WindowFeatures.h>
@@ -102,7 +103,7 @@ template<> struct ClientTraits<WKPageLoaderClientBase> {
 };
 
 template<> struct ClientTraits<WKPageNavigationClientBase> {
-    typedef std::tuple<WKPageNavigationClientV0, WKPageNavigationClientV1, WKPageNavigationClientV2> Versions;
+    typedef std::tuple<WKPageNavigationClientV0, WKPageNavigationClientV1, WKPageNavigationClientV2, WKPageNavigationClientV3> Versions;
 };
 
 template<> struct ClientTraits<WKPagePolicyClientBase> {
@@ -2276,6 +2277,13 @@ void WKPageSetPageNavigationClient(WKPageRef pageRef, const WKPageNavigationClie
             return API::Data::create(masterKey.data(), masterKey.size());
         }
 
+        RefPtr<API::String> signedPublicKeyAndChallengeString(WebPageProxy& page, unsigned keySizeIndex, const RefPtr<API::String>& challengeString, const WebCore::URL& url) override
+        {
+            if (m_client.copySignedPublicKeyAndChallengeString)
+                return adoptRef(toImpl(m_client.copySignedPublicKeyAndChallengeString(toAPI(&page), m_client.base.clientInfo)));
+            return API::String::create(WebCore::signedPublicKeyAndChallengeString(keySizeIndex, challengeString->string(), url));
+        }
+
         void didBeginNavigationGesture(WebPageProxy& page) override
         {
             if (!m_client.didBeginNavigationGesture)
index 14843d2..3806d18 100644 (file)
@@ -69,6 +69,8 @@ typedef void (*WKPageNavigationWebProcessDidCrashCallback)(WKPageRef page, const
 typedef void (*WKPageNavigationWebProcessDidTerminateCallback)(WKPageRef page, WKProcessTerminationReason reason, const void* clientInfo);
 
 typedef WKDataRef (*WKPageNavigationCopyWebCryptoMasterKeyCallback)(WKPageRef page, const void* clientInfo);
+
+typedef WKStringRef (*WKPageNavigationCopySignedPublicKeyAndChallengeStringCallback)(WKPageRef page, const void* clientInfo);
     
 typedef WKPluginLoadPolicy (*WKPageNavigationDecidePolicyForPluginLoadCallback)(WKPageRef page, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInfoDictionary, WKStringRef* unavailabilityDescription, const void* clientInfo);
 
@@ -177,6 +179,42 @@ typedef struct WKPageNavigationClientV2 {
     WKPageNavigationContentRuleListNotificationCallback contentRuleListNotification;
 } WKPageNavigationClientV2;
 
+typedef struct WKPageNavigationClientV3 {
+    WKPageNavigationClientBase base;
+
+    // Version 0.
+    WKPageNavigationDecidePolicyForNavigationActionCallback decidePolicyForNavigationAction;
+    WKPageNavigationDecidePolicyForNavigationResponseCallback decidePolicyForNavigationResponse;
+    WKPageNavigationDecidePolicyForPluginLoadCallback decidePolicyForPluginLoad;
+    WKPageNavigationDidStartProvisionalNavigationCallback didStartProvisionalNavigation;
+    WKPageNavigationDidReceiveServerRedirectForProvisionalNavigationCallback didReceiveServerRedirectForProvisionalNavigation;
+    WKPageNavigationDidFailProvisionalNavigationCallback didFailProvisionalNavigation;
+    WKPageNavigationDidCommitNavigationCallback didCommitNavigation;
+    WKPageNavigationDidFinishNavigationCallback didFinishNavigation;
+    WKPageNavigationDidFailNavigationCallback didFailNavigation;
+    WKPageNavigationDidFailProvisionalLoadInSubframeCallback didFailProvisionalLoadInSubframe;
+    WKPageNavigationDidFinishDocumentLoadCallback didFinishDocumentLoad;
+    WKPageNavigationDidSameDocumentNavigationCallback didSameDocumentNavigation;
+    WKPageNavigationRenderingProgressDidChangeCallback renderingProgressDidChange;
+    WKPageNavigationCanAuthenticateAgainstProtectionSpaceCallback canAuthenticateAgainstProtectionSpace;
+    WKPageNavigationDidReceiveAuthenticationChallengeCallback didReceiveAuthenticationChallenge;
+    WKPageNavigationWebProcessDidCrashCallback webProcessDidCrash;
+    WKPageNavigationCopyWebCryptoMasterKeyCallback copyWebCryptoMasterKey;
+    WKPageNavigationDidBeginNavigationGesture didBeginNavigationGesture;
+    WKPageNavigationWillEndNavigationGesture willEndNavigationGesture;
+    WKPageNavigationDidEndNavigationGesture didEndNavigationGesture;
+    WKPageNavigationDidRemoveNavigationGestureSnapshot didRemoveNavigationGestureSnapshot;
+
+    // Version 1.
+    WKPageNavigationWebProcessDidTerminateCallback webProcessDidTerminate;
+
+    // Version 2.
+    WKPageNavigationContentRuleListNotificationCallback contentRuleListNotification;
+
+    // Version 3.
+    WKPageNavigationCopySignedPublicKeyAndChallengeStringCallback copySignedPublicKeyAndChallengeString;
+} WKPageNavigationClientV3;
+
 #ifdef __cplusplus
 }
 #endif
index bb86d61..b273dbd 100644 (file)
@@ -111,6 +111,8 @@ private:
 
         RefPtr<API::Data> webCryptoMasterKey(WebPageProxy&) override;
 
+        RefPtr<API::String> signedPublicKeyAndChallengeString(WebPageProxy&, unsigned keySizeIndex, const RefPtr<API::String>& challengeString, const WebCore::URL&) override;
+
 #if USE(QUICK_LOOK)
         void didStartLoadForQuickLookDocumentInMainFrame(const WTF::String& fileName, const WTF::String& uti) override;
         void didFinishLoadForQuickLookDocumentInMainFrame(const QuickLookDocumentData&) override;
index a09a20a..809e5a0 100644 (file)
@@ -66,6 +66,7 @@
 #import "_WKSameDocumentNavigationTypeInternal.h"
 #import "_WKWebsitePoliciesInternal.h"
 #import <WebCore/Credential.h>
+#import <WebCore/SSLKeyGenerator.h>
 #import <WebCore/SecurityOriginData.h>
 #import <WebCore/SerializedCryptoKeyWrap.h>
 #import <WebCore/URL.h>
@@ -1047,6 +1048,12 @@ RefPtr<API::Data> NavigationState::NavigationClient::webCryptoMasterKey(WebPageP
     }, data.leakRef());
 }
 
+RefPtr<API::String> NavigationState::NavigationClient::signedPublicKeyAndChallengeString(WebPageProxy& page, unsigned keySizeIndex, const RefPtr<API::String>& challengeString, const WebCore::URL& url)
+{
+    // WebKitTestRunner uses C API. Hence, no SPI is provided to override the following function.
+    return API::String::create(WebCore::signedPublicKeyAndChallengeString(keySizeIndex, challengeString->string(), url));
+}
+
 #if USE(QUICK_LOOK)
 void NavigationState::NavigationClient::didStartLoadForQuickLookDocumentInMainFrame(const String& fileName, const String& uti)
 {
index 560b883..bbc52aa 100644 (file)
 #include <WebCore/PerformanceLoggingClient.h>
 #include <WebCore/PublicSuffix.h>
 #include <WebCore/RenderEmbeddedObject.h>
+#include <WebCore/SSLKeyGenerator.h>
 #include <WebCore/SerializedCryptoKeyWrap.h>
 #include <WebCore/SharedBuffer.h>
 #include <WebCore/TextCheckerClient.h>
@@ -6789,6 +6790,18 @@ void WebPageProxy::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, bool& succ
 }
 #endif
 
+void WebPageProxy::signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const WebCore::URL& url, String& result)
+{
+    PageClientProtector protector(m_pageClient);
+
+    if (m_navigationClient) {
+        if (auto apiString = m_navigationClient->signedPublicKeyAndChallengeString(*this, keySizeIndex, API::String::create(challengeString), url))
+            result = apiString->string();
+        return;
+    }
+    result = WebCore::signedPublicKeyAndChallengeString(keySizeIndex, challengeString, url);
+}
+
 void WebPageProxy::addMIMETypeWithCustomContentProvider(const String& mimeType)
 {
     m_process->send(Messages::WebPage::AddMIMETypeWithCustomContentProvider(mimeType), m_pageID);
index f12325a..b53445f 100644 (file)
@@ -1119,6 +1119,8 @@ public:
     void unwrapCryptoKey(const Vector<uint8_t>&, bool& succeeded, Vector<uint8_t>&);
 #endif
 
+    void signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const WebCore::URL&, String& result);
+
     void takeSnapshot(WebCore::IntRect, WebCore::IntSize bitmapSize, SnapshotOptions, WTF::Function<void (const ShareableBitmap::Handle&, CallbackBase::Error)>&&);
 
     void navigationGestureDidBegin();
index 8cb3c41..6efd88e 100644 (file)
@@ -523,4 +523,7 @@ messages -> WebPageProxy {
     StartDisplayLink(unsigned observerID)
     StopDisplayLink(unsigned observerID)
 #endif
+
+    SignedPublicKeyAndChallengeString(unsigned keySizeIndex, String challengeString, WebCore::URL url) -> (String result)
+
 }
index b623f76..621ea39 100644 (file)
@@ -1164,6 +1164,14 @@ bool WebChromeClient::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<
 
 #endif
 
+String WebChromeClient::signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const WebCore::URL& url) const
+{
+    String result;
+    if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::SignedPublicKeyAndChallengeString(keySizeIndex, challengeString, url), Messages::WebPageProxy::SignedPublicKeyAndChallengeString::Reply(result), m_page.pageID()))
+        return emptyString();
+    return result;
+}
+
 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC)
 
 void WebChromeClient::handleTelephoneNumberClick(const String& number, const IntPoint& point)
index caecf29..321b522 100644 (file)
@@ -315,6 +315,8 @@ private:
     bool unwrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) const final;
 #endif
 
+    String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const WebCore::URL&) const final;
+
 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC)
     void handleTelephoneNumberClick(const String& number, const WebCore::IntPoint&) final;
 #endif
index 3027d09..07d48cd 100644 (file)
@@ -1,3 +1,21 @@
+2018-04-25  Jiewen Tan  <jiewen_tan@apple.com>
+
+        Remove access to keychain from the WebContent process
+        https://bugs.webkit.org/show_bug.cgi?id=184428
+        <rdar://problem/13150903>
+
+        Reviewed by Brent Fulgham.
+
+        This patch does the followings:
+        1. Added necessary support to move HTMLKeygenElement's operation from WebCore space to Client space.
+        2. Craft new SPI signedPublicKeyAndChallengeStringForWebView to supply HTMLKeygenElement with dummy data
+        such that DumpRenderTree tests will not modify the underlying key store (e.g., the macOS Keychain).
+
+        * WebCoreSupport/WebChromeClient.h:
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::signedPublicKeyAndChallengeString const):
+        * WebView/WebUIDelegatePrivate.h:
+
 2018-04-24  Jer Noble  <jer.noble@apple.com>
 
         Don't add system framework paths to FRAMEWORK_SEARCH_PATHS
index 4ae39d1..424c91a 100644 (file)
@@ -221,5 +221,7 @@ private:
     void setMockMediaPlaybackTargetPickerState(const String&, WebCore::MediaPlaybackTargetContext::State) final;
 #endif
 
+    String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const WebCore::URL&) const final;
+
     WebView *m_webView;
 };
index 3626369..81fe21d 100644 (file)
@@ -79,6 +79,7 @@
 #import <WebCore/Page.h>
 #import <WebCore/PlatformScreen.h>
 #import <WebCore/ResourceRequest.h>
+#import <WebCore/SSLKeyGenerator.h>
 #import <WebCore/SerializedCryptoKeyWrap.h>
 #import <WebCore/Widget.h>
 #import <WebCore/WindowFeatures.h>
@@ -1124,3 +1125,11 @@ void WebChromeClient::setMockMediaPlaybackTargetPickerState(const String& name,
 }
 
 #endif
+
+String WebChromeClient::signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const WebCore::URL& url) const
+{
+    SEL selector = @selector(signedPublicKeyAndChallengeStringForWebView:);
+    if ([[m_webView UIDelegate] respondsToSelector:selector])
+        return CallUIDelegate(m_webView, selector);
+    return WebCore::signedPublicKeyAndChallengeString(keySizeIndex, challengeString, url);
+}
index f9fce6f..a4f3a4e 100644 (file)
@@ -308,4 +308,6 @@ extern NSString *WebConsoleMessageErrorMessageLevel;
 
 - (NSData *)webCryptoMasterKeyForWebView:(WebView *)sender;
 
+- (NSString *)signedPublicKeyAndChallengeStringForWebView:(WebView *)sender;
+
 @end
index 876a32c..de44b25 100644 (file)
@@ -1,3 +1,27 @@
+2018-04-25  Jiewen Tan  <jiewen_tan@apple.com>
+
+        Remove access to keychain from the WebContent process
+        https://bugs.webkit.org/show_bug.cgi?id=184428
+        <rdar://problem/13150903>
+
+        Reviewed by Brent Fulgham.
+
+        This patch does the followings:
+        1. Added an API test for this patch.
+        2. Instrument DumpRenderTree and WebKitTestRunner to take advantages of new SPIs.
+
+        * DumpRenderTree/mac/UIDelegate.mm:
+        (-[UIDelegate signedPublicKeyAndChallengeStringForWebView:]):
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/mac/SSLKeyGenerator.mm: Added.
+        (TestWebKitAPI::SSLKeyGeneratorTest::SetUp):
+        (TestWebKitAPI::SSLKeyGeneratorTest::TearDown):
+        (TestWebKitAPI::TEST_F):
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::copySignedPublicKeyAndChallengeString):
+        (WTR::TestController::createOtherPage):
+        (WTR::TestController::createWebViewWithOptions):
+
 2018-04-25  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [Extra zoom mode] The search field on www.bing.com is missing label text
index 4b95a2f..386a174 100644 (file)
@@ -368,6 +368,12 @@ DumpRenderTreeDraggingInfo *draggingInfo = nil;
     return [NSData dataWithBytes:"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" length:16];
 }
 
+- (NSString *)signedPublicKeyAndChallengeStringForWebView:(WebView *)sender
+{
+    // Any fake response would do, all we need for testing is to implement the callback.
+    return @"MIHFMHEwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAnX0TILJrOMUue%2BPtwBRE6XfV%0AWtKQbsshxk5ZhcUwcwyvcnIq9b82QhJdoACdD34rqfCAIND46fXKQUnb0mvKzQID%0AAQABFhFNb3ppbGxhSXNNeUZyaWVuZDANBgkqhkiG9w0BAQQFAANBAAKv2Eex2n%2FS%0Ar%2F7iJNroWlSzSMtTiQTEB%2BADWHGj9u1xrUrOilq%2Fo2cuQxIfZcNZkYAkWP4DubqW%0Ai0%2F%2FrgBvmco%3D";
+}
+
 - (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener allowMultipleFiles:(BOOL)allowMultipleFiles
 {
     printf("OPEN FILE PANEL\n");
index a376e26..6111112 100644 (file)
                5797FE311EB15A6800B2F4A0 /* NavigationClientDefaultCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5797FE2F1EB15A5F00B2F4A0 /* NavigationClientDefaultCrypto.cpp */; };
                5797FE331EB15AB100B2F4A0 /* navigation-client-default-crypto.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5797FE321EB15A8900B2F4A0 /* navigation-client-default-crypto.html */; };
                57C3FA661F7C248F009D4B80 /* WeakPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CB9BC371A67482300FE5678 /* WeakPtr.cpp */; };
+               57F4AAA0208FAEF000A68E9E /* SSLKeyGenerator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57F4AA9F208FA83D00A68E9E /* SSLKeyGenerator.mm */; };
                57F56A5C1C7F8CC100F31D7E /* IsNavigationActionTrusted.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57F56A5B1C7F8A4000F31D7E /* IsNavigationActionTrusted.html */; };
                5C0BF88D1DD5964D00B00328 /* MemoryPressureHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C0BF88C1DD5957400B00328 /* MemoryPressureHandler.mm */; };
                5C0BF8911DD599A900B00328 /* WebViewCanPasteZeroPng.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C0BF88F1DD5999B00B00328 /* WebViewCanPasteZeroPng.mm */; };
                5797FE321EB15A8900B2F4A0 /* navigation-client-default-crypto.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "navigation-client-default-crypto.html"; sourceTree = "<group>"; };
                5798E2AF1CAF5C2800C5CBA0 /* ProvisionalURLNotChange.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ProvisionalURLNotChange.mm; sourceTree = "<group>"; };
                57F10D921C7E7B3800ECDF30 /* IsNavigationActionTrusted.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IsNavigationActionTrusted.mm; sourceTree = "<group>"; };
+               57F4AA9F208FA83D00A68E9E /* SSLKeyGenerator.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SSLKeyGenerator.mm; sourceTree = "<group>"; };
                57F56A5B1C7F8A4000F31D7E /* IsNavigationActionTrusted.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IsNavigationActionTrusted.html; sourceTree = "<group>"; };
                5C0BF88C1DD5957400B00328 /* MemoryPressureHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryPressureHandler.mm; sourceTree = "<group>"; };
                5C0BF88F1DD5999B00B00328 /* WebViewCanPasteZeroPng.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewCanPasteZeroPng.mm; sourceTree = "<group>"; };
                                261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */,
                                52B8CF9515868CF000281053 /* SetDocumentURI.mm */,
                                C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */,
+                               57F4AA9F208FA83D00A68E9E /* SSLKeyGenerator.mm */,
                                291861FD17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm */,
                                E194E1BA177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm */,
                                3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */,
                                2DFF7B6D1DA487AF00814614 /* SnapshotStore.mm in Sources */,
                                0F4FFA9E1ED3AA8500F7111F /* SnapshotViaRenderInContext.mm in Sources */,
                                7CCE7F151A411AE600447C4C /* SpacebarScrolling.cpp in Sources */,
+                               57F4AAA0208FAEF000A68E9E /* SSLKeyGenerator.mm in Sources */,
                                7CCE7EF21A411AE600447C4C /* StopLoadingDuringDidFailProvisionalLoad.cpp in Sources */,
                                7CCE7ECE1A411A7E00447C4C /* StopLoadingFromDidFinishLoading.mm in Sources */,
                                7CCE7ECF1A411A7E00447C4C /* StopLoadingFromDidReceiveResponse.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/mac/SSLKeyGenerator.mm b/Tools/TestWebKitAPI/Tests/mac/SSLKeyGenerator.mm
new file mode 100644 (file)
index 0000000..d8c748c
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#import <Security/SecAsn1Coder.h>
+#import <Security/SecAsn1Templates.h>
+#import <WebCore/LocalizedStrings.h>
+#import <WebCore/SSLKeyGenerator.h>
+#import <WebCore/URL.h>
+#import <wtf/MainThread.h>
+#import <wtf/Scope.h>
+#import <wtf/spi/cocoa/SecuritySPI.h>
+#import <wtf/text/Base64.h>
+
+#if USE(APPLE_INTERNAL_SDK)
+#include <Security/SecKeyPriv.h>
+#else
+extern const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5;
+#endif
+
+namespace TestWebKitAPI {
+
+struct PublicKeyAndChallenge {
+    SecAsn1PubKeyInfo subjectPublicKeyInfo;
+    SecAsn1Item challenge;
+};
+
+struct SignedPublicKeyAndChallenge {
+    PublicKeyAndChallenge publicKeyAndChallenge;
+    SecAsn1AlgId algorithmIdentifier;
+    SecAsn1Item signature;
+};
+
+const SecAsn1Template publicKeyAndChallengeTemplate[] {
+    { SEC_ASN1_SEQUENCE, 0, nullptr, sizeof(PublicKeyAndChallenge) },
+    { SEC_ASN1_INLINE, offsetof(PublicKeyAndChallenge, subjectPublicKeyInfo), kSecAsn1SubjectPublicKeyInfoTemplate, 0},
+    { SEC_ASN1_INLINE, offsetof(PublicKeyAndChallenge, challenge), kSecAsn1IA5StringTemplate, 0 },
+    { 0, 0, 0, 0}
+};
+
+const SecAsn1Template signedPublicKeyAndChallengeTemplate[] {
+    { SEC_ASN1_SEQUENCE, 0, nullptr, sizeof(SignedPublicKeyAndChallenge) },
+    { SEC_ASN1_INLINE, offsetof(SignedPublicKeyAndChallenge, publicKeyAndChallenge), publicKeyAndChallengeTemplate, 0 },
+    { SEC_ASN1_INLINE, offsetof(SignedPublicKeyAndChallenge, algorithmIdentifier), kSecAsn1AlgorithmIDTemplate, 0 },
+    { SEC_ASN1_BIT_STRING, offsetof(SignedPublicKeyAndChallenge, signature), 0, 0 },
+    { 0, 0, 0, 0 }
+};
+
+const WebCore::URL url = WebCore::URL(WebCore::URL(), "http://www.webkit.org/");
+
+class SSLKeyGeneratorTest : public testing::Test {
+public:
+    virtual void SetUp()
+    {
+        WTF::initializeMainThread();
+    }
+
+    virtual void TearDown()
+    {
+        SecItemDelete((__bridge CFDictionaryRef) @{
+            (id)kSecClass: (id)kSecClassKey,
+            (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
+            (id)kSecAttrLabel: WebCore::keygenKeychainItemName(url.host()),
+        });
+        SecItemDelete((__bridge CFDictionaryRef) @{
+            (id)kSecClass: (id)kSecClassKey,
+            (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPublic,
+            (id)kSecAttrLabel: WebCore::keygenKeychainItemName(url.host()),
+        });
+    }
+};
+
+TEST_F(SSLKeyGeneratorTest, DefaultTest)
+{
+    char challenge[] = "0123456789";
+    auto rawResult = WebCore::signedPublicKeyAndChallengeString(0, challenge, url);
+    ASSERT_FALSE(rawResult.isEmpty());
+    Vector<uint8_t> derResult;
+    ASSERT_TRUE(base64Decode(rawResult, derResult));
+
+    SecAsn1CoderRef coder = nullptr;
+    ASSERT_EQ(errSecSuccess, SecAsn1CoderCreate(&coder));
+    auto releaseCoder = makeScopeExit([&coder] {
+        SecAsn1CoderRelease(coder);
+    });
+
+    SignedPublicKeyAndChallenge decodedResult { };
+    SecAsn1Item derResultItem { derResult.size(), derResult.data() };
+    ASSERT_EQ(errSecSuccess, SecAsn1DecodeData(coder, &derResultItem, signedPublicKeyAndChallengeTemplate, &decodedResult));
+
+    // Check challenge
+    EXPECT_FALSE(memcmp(challenge, decodedResult.publicKeyAndChallenge.challenge.Data, sizeof(challenge)));
+
+    // Check signature
+    RetainPtr<SecKeyRef> publicKey = nullptr;
+    {
+        NSDictionary* options = @{
+            (id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA,
+            (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPublic,
+            (id)kSecAttrKeySizeInBits: @2048,
+        };
+        CFErrorRef errorRef = nullptr;
+        publicKey = adoptCF(SecKeyCreateWithData(
+            adoptCF(CFDataCreate(NULL, decodedResult.publicKeyAndChallenge.subjectPublicKeyInfo.subjectPublicKey.Data, decodedResult.publicKeyAndChallenge.subjectPublicKeyInfo.subjectPublicKey.Length)).get(),
+            (__bridge CFDictionaryRef)options,
+            &errorRef
+        ));
+        ASSERT_FALSE(errorRef);
+    }
+
+    SecAsn1Item dataToVerify { 0, nullptr };
+    ASSERT_EQ(errSecSuccess, SecAsn1EncodeItem(coder, &decodedResult.publicKeyAndChallenge, publicKeyAndChallengeTemplate, &dataToVerify));
+
+    // Signature's Length is in bits, we need it in bytes.
+    EXPECT_TRUE(SecKeyVerifySignature(publicKey.get(), kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5, adoptCF(CFDataCreate(NULL, dataToVerify.Data, dataToVerify.Length)).get(), adoptCF(CFDataCreate(NULL, decodedResult.signature.Data, decodedResult.signature.Length / 8)).get(), NULL));
+
+    // Check OIDs
+    EXPECT_FALSE(memcmp(oidMd5Rsa.data, decodedResult.algorithmIdentifier.algorithm.Data, oidMd5Rsa.length));
+    EXPECT_FALSE(memcmp(oidRsa.data, decodedResult.publicKeyAndChallenge.subjectPublicKeyInfo.algorithm.algorithm.Data, oidRsa.length));
+
+}
+
+} // namespace TestWebKitAPI
index 6965cdd..68c49c8 100644 (file)
@@ -108,6 +108,12 @@ static WKDataRef copyWebCryptoMasterKey(WKPageRef, const void*)
     return WKDataCreate((const uint8_t*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16);
 }
 
+static WKStringRef copySignedPublicKeyAndChallengeString(WKPageRef, const void*)
+{
+    // Any fake response would do, all we need for testing is to implement the callback.
+    return WKStringCreateWithUTF8CString("MIHFMHEwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAnX0TILJrOMUue%2BPtwBRE6XfV%0AWtKQbsshxk5ZhcUwcwyvcnIq9b82QhJdoACdD34rqfCAIND46fXKQUnb0mvKzQID%0AAQABFhFNb3ppbGxhSXNNeUZyaWVuZDANBgkqhkiG9w0BAQQFAANBAAKv2Eex2n%2FS%0Ar%2F7iJNroWlSzSMtTiQTEB%2BADWHGj9u1xrUrOilq%2Fo2cuQxIfZcNZkYAkWP4DubqW%0Ai0%2F%2FrgBvmco%3D");
+}
+
 static TestController* controller;
 
 TestController& TestController::singleton()
@@ -299,8 +305,8 @@ WKPageRef TestController::createOtherPage(WKPageRef oldPage, WKPageConfiguration
     };
     WKPageSetPageUIClient(newPage, &otherPageUIClient.base);
     
-    WKPageNavigationClientV0 pageNavigationClient = {
-        { 0, &TestController::singleton() },
+    WKPageNavigationClientV3 pageNavigationClient = {
+        { 3, &TestController::singleton() },
         decidePolicyForNavigationAction,
         decidePolicyForNavigationResponse,
         decidePolicyForPluginLoad,
@@ -321,7 +327,10 @@ WKPageRef TestController::createOtherPage(WKPageRef oldPage, WKPageConfiguration
         didBeginNavigationGesture,
         willEndNavigationGesture,
         didEndNavigationGesture,
-        didRemoveNavigationGestureSnapshot
+        didRemoveNavigationGestureSnapshot,
+        0, // webProcessDidTerminate
+        0, // contentRuleListNotification
+        copySignedPublicKeyAndChallengeString
     };
     WKPageSetPageNavigationClient(newPage, &pageNavigationClient.base);
 
@@ -580,8 +589,8 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
     };
     WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient.base);
 
-    WKPageNavigationClientV0 pageNavigationClient = {
-        { 0, this },
+    WKPageNavigationClientV3 pageNavigationClient = {
+        { 3, this },
         decidePolicyForNavigationAction,
         decidePolicyForNavigationResponse,
         decidePolicyForPluginLoad,
@@ -602,7 +611,10 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
         didBeginNavigationGesture,
         willEndNavigationGesture,
         didEndNavigationGesture,
-        didRemoveNavigationGestureSnapshot
+        didRemoveNavigationGestureSnapshot,
+        0, // webProcessDidTerminate
+        0, // contentRuleListNotification
+        copySignedPublicKeyAndChallengeString
     };
     WKPageSetPageNavigationClient(m_mainWebView->page(), &pageNavigationClient.base);