[WebAuthN] Adopt SecurityOrigin::isMatchingRegistrableDomainSuffix()
authorjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 May 2019 02:20:51 +0000 (02:20 +0000)
committerjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 May 2019 02:20:51 +0000 (02:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197481

Reviewed by Brent Fulgham.

Source/WebCore:

This patch implements Step 6-7 from:
https://www.w3.org/TR/webauthn/#createCredential,
https://www.w3.org/TR/webauthn/#discover-from-external-source.

Test: http/wpt/webauthn/public-key-credential-ip-address.html

* Modules/webauthn/AuthenticatorCoordinator.cpp:
(WebCore::AuthenticatorCoordinator::create const):
(WebCore::AuthenticatorCoordinator::discoverFromExternalSource const):

LayoutTests:

* http/wpt/webauthn/public-key-credential-create-failure.https.html:
* http/wpt/webauthn/public-key-credential-get-failure.https.html:
* http/wpt/webauthn/public-key-credential-ip-address-expected.txt: Added.
* http/wpt/webauthn/public-key-credential-ip-address.html: Added.
* http/wpt/webauthn/resources/public-key-credential-ip-address.https.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https.html
LayoutTests/http/wpt/webauthn/public-key-credential-get-failure.https.html
LayoutTests/http/wpt/webauthn/public-key-credential-ip-address-expected.txt [new file with mode: 0644]
LayoutTests/http/wpt/webauthn/public-key-credential-ip-address.html [new file with mode: 0644]
LayoutTests/http/wpt/webauthn/resources/public-key-credential-ip-address.https.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp

index b7cec96..9e711b6 100644 (file)
@@ -1,3 +1,16 @@
+2019-05-01  Jiewen Tan  <jiewen_tan@apple.com>
+
+        [WebAuthN] Adopt SecurityOrigin::isMatchingRegistrableDomainSuffix()
+        https://bugs.webkit.org/show_bug.cgi?id=197481
+
+        Reviewed by Brent Fulgham.
+
+        * http/wpt/webauthn/public-key-credential-create-failure.https.html:
+        * http/wpt/webauthn/public-key-credential-get-failure.https.html:
+        * http/wpt/webauthn/public-key-credential-ip-address-expected.txt: Added.
+        * http/wpt/webauthn/public-key-credential-ip-address.html: Added.
+        * http/wpt/webauthn/resources/public-key-credential-ip-address.https.html: Added.
+
 2019-05-01  Devin Rousso  <drousso@apple.com>
 
         Unreviewed, fix test failures after r242809.
index 9ea3428..4e131cb 100644 (file)
@@ -47,7 +47,7 @@
         };
 
         return promiseRejects(t, "SecurityError",
-            navigator.credentials.create(options), "The origin of the document is not a registrable domain suffix of the provided RP ID.");
+            navigator.credentials.create(options), "The provided RP ID is not a registrable domain suffix of the effective domain of the document.");
     }, "PublicKeyCredential's [[create]] with a mismatched RP ID");
 
     promise_test(function(t) {
index a245690..8547fd8 100644 (file)
@@ -29,7 +29,7 @@
         };
 
         return promiseRejects(t, "SecurityError",
-            navigator.credentials.get(options), "The origin of the document is not a registrable domain suffix of the provided RP ID.");
+            navigator.credentials.get(options), "The provided RP ID is not a registrable domain suffix of the effective domain of the document.");
     }, "PublicKeyCredential's [[get]] with a mismatched RP ID");
 
     promise_test(t => {
diff --git a/LayoutTests/http/wpt/webauthn/public-key-credential-ip-address-expected.txt b/LayoutTests/http/wpt/webauthn/public-key-credential-ip-address-expected.txt
new file mode 100644 (file)
index 0000000..b14be5c
--- /dev/null
@@ -0,0 +1,4 @@
+
+PASS PublicKeyCredential's [[create]] with ip addresses. 
+PASS PublicKeyCredential's [[get]] with ip addresses. 
+
diff --git a/LayoutTests/http/wpt/webauthn/public-key-credential-ip-address.html b/LayoutTests/http/wpt/webauthn/public-key-credential-ip-address.html
new file mode 100644 (file)
index 0000000..760286c
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<script>
+    if (window.testRunner) {
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+    }
+    location="https://127.0.0.1:9443/WebKit/webauthn/resources/public-key-credential-ip-address.https.html"
+</script>
diff --git a/LayoutTests/http/wpt/webauthn/resources/public-key-credential-ip-address.https.html b/LayoutTests/http/wpt/webauthn/resources/public-key-credential-ip-address.https.html
new file mode 100644 (file)
index 0000000..6de3a94
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<title>Web Authentication API: Invoke PublicKeyCredential in ip addresses.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="util.js"></script>
+<script>
+    // Default mock configuration. Tests need to override if they need different configuration.
+    if (window.testRunner)
+        testRunner.setWebAuthenticationMockConfiguration({ });
+
+    promise_test(function(t) {
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "example.com",
+                },
+                user: {
+                    name: "John Appleseed",
+                    id: asciiToUint8Array("123456"),
+                    displayName: "John",
+                },
+                challenge: asciiToUint8Array("123456"),
+                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+            }
+        };
+
+        return promiseRejects(t, "SecurityError",
+            navigator.credentials.create(options), "The effective domain of the document is not a valid domain.");
+    }, "PublicKeyCredential's [[create]] with ip addresses.");
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                challenge: asciiToUint8Array("123456")
+            }
+        };
+
+        return promiseRejects(t, "SecurityError",
+            navigator.credentials.get(options), "The effective domain of the document is not a valid domain.");
+    }, "PublicKeyCredential's [[get]] with ip addresses.");
+</script>
index 1f7b771..70a4440 100644 (file)
@@ -1,3 +1,20 @@
+2019-05-01  Jiewen Tan  <jiewen_tan@apple.com>
+
+        [WebAuthN] Adopt SecurityOrigin::isMatchingRegistrableDomainSuffix()
+        https://bugs.webkit.org/show_bug.cgi?id=197481
+
+        Reviewed by Brent Fulgham.
+
+        This patch implements Step 6-7 from:
+        https://www.w3.org/TR/webauthn/#createCredential,
+        https://www.w3.org/TR/webauthn/#discover-from-external-source.
+
+        Test: http/wpt/webauthn/public-key-credential-ip-address.html
+
+        * Modules/webauthn/AuthenticatorCoordinator.cpp:
+        (WebCore::AuthenticatorCoordinator::create const):
+        (WebCore::AuthenticatorCoordinator::discoverFromExternalSource const):
+
 2019-05-01  Youenn Fablet  <youenn@apple.com>
 
         Add back hasNullReferences() assert in Document::updateIsPlayingMedia
index d263c1b..9573927 100644 (file)
@@ -126,16 +126,21 @@ void AuthenticatorCoordinator::create(const SecurityOrigin& callerOrigin, const
         return;
     }
 
-    // Step 5-7.
-    // FIXME(181950): We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not.
-    // Step 6 is therefore skipped. Also, we lack the support to determine whether a domain is a registrable
-    // domain suffix of another domain. Hence restrict the comparison to equal in Step 7.
-    if (!options.rp.id.isEmpty() && callerOrigin.host() != options.rp.id) {
-        promise.reject(Exception { SecurityError, "The origin of the document is not a registrable domain suffix of the provided RP ID."_s });
+    // Step 5. Skipped since SecurityOrigin doesn't have the concept of "opaque origin".
+    // Step 6. The effective domain may be represented in various manners, such as a domain or an ip address.
+    // Only the domain format of host is permitted in WebAuthN.
+    if (URL::hostIsIPAddress(callerOrigin.domain())) {
+        promise.reject(Exception { SecurityError, "The effective domain of the document is not a valid domain."_s });
+        return;
+    }
+
+    // Step 7.
+    if (!options.rp.id.isEmpty() && !callerOrigin.isMatchingRegistrableDomainSuffix(options.rp.id)) {
+        promise.reject(Exception { SecurityError, "The provided RP ID is not a registrable domain suffix of the effective domain of the document."_s });
         return;
     }
     if (options.rp.id.isEmpty())
-        options.rp.id = callerOrigin.host();
+        options.rp.id = callerOrigin.domain();
 
     // Step 8-10.
     // Most of the jobs are done by bindings. However, we can't know if the JSValue of options.pubKeyCredParams
@@ -188,16 +193,21 @@ void AuthenticatorCoordinator::discoverFromExternalSource(const SecurityOrigin&
         return;
     }
 
-    // Step 5-7.
-    // FIXME(181950): We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not.
-    // Step 6 is therefore skipped. Also, we lack the support to determine whether a domain is a registrable
-    // domain suffix of another domain. Hence restrict the comparison to equal in Step 7.
-    if (!options.rpId.isEmpty() && callerOrigin.host() != options.rpId) {
-        promise.reject(Exception { SecurityError, "The origin of the document is not a registrable domain suffix of the provided RP ID."_s });
+    // Step 5. Skipped since SecurityOrigin doesn't have the concept of "opaque origin".
+    // Step 6. The effective domain may be represented in various manners, such as a domain or an ip address.
+    // Only the domain format of host is permitted in WebAuthN.
+    if (URL::hostIsIPAddress(callerOrigin.domain())) {
+        promise.reject(Exception { SecurityError, "The effective domain of the document is not a valid domain."_s });
+        return;
+    }
+
+    // Step 7.
+    if (!options.rpId.isEmpty() && !callerOrigin.isMatchingRegistrableDomainSuffix(options.rpId)) {
+        promise.reject(Exception { SecurityError, "The provided RP ID is not a registrable domain suffix of the effective domain of the document."_s });
         return;
     }
     if (options.rpId.isEmpty())
-        options.rpId = callerOrigin.host();
+        options.rpId = callerOrigin.domain();
 
     // Step 8-9.
     // Only FIDO AppID Extension is supported.