Title: [256062] trunk
Revision
256062
Author
[email protected]
Date
2020-02-07 14:16:54 -0800 (Fri, 07 Feb 2020)

Log Message

[WebAuthn] Report CTAP Client Pin Error to clients
https://bugs.webkit.org/show_bug.cgi?id=205837
<rdar://problem/58356872>

Reviewed by Brent Fulgham.

Source/WebKit:

Authenticators could return four different errors { kCtap2ErrPinInvalid, kCtap2ErrPinBlocked, kCtap2ErrPinAuthInvalid, kCtap2ErrPinAuthBlocked }
during 1) GetPinToken or 2) MakeCredential/GetAssertion with PinAuth.

All errors should be reported to the client so that appropriate UI can be displayed to users.
For kCtap2ErrPinAuthInvalid and kCtap2ErrPinInvalid, we will restart the whole Pin process to get
another Pin from the user.

Covered by API tests.

* UIProcess/API/APIWebAuthenticationPanelClient.h:
* UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm:
(WebKit::wkWebAuthenticationPanelUpdate):
* UIProcess/WebAuthentication/WebAuthenticationFlags.h:
* UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:
(WebKit::fido::toStatus):
(WebKit::fido::isPinError):
(WebKit::CtapAuthenticator::continueMakeCredentialAfterResponseReceived):
(WebKit::CtapAuthenticator::continueGetAssertionAfterResponseReceived):
(WebKit::CtapAuthenticator::continueRequestAfterGetPinToken):
(WebKit::CtapAuthenticator::tryRestartPin):
* UIProcess/WebAuthentication/fido/CtapAuthenticator.h:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
(-[TestWebAuthenticationPanelDelegate panel:updateWebAuthenticationPanel:]):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-auth-blocked-error.html: Copied from Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html.
* TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-invalid-error-retry.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-auth-blocked-error.html: Copied from Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html.
* TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html: Copied from Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html.
* TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html: Renamed from Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html.
* TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-invalid-error-retry.html: Added.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (256061 => 256062)


--- trunk/Source/WebKit/ChangeLog	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Source/WebKit/ChangeLog	2020-02-07 22:16:54 UTC (rev 256062)
@@ -1,3 +1,33 @@
+2020-02-07  Jiewen Tan  <[email protected]>
+
+        [WebAuthn] Report CTAP Client Pin Error to clients
+        https://bugs.webkit.org/show_bug.cgi?id=205837
+        <rdar://problem/58356872>
+
+        Reviewed by Brent Fulgham.
+
+        Authenticators could return four different errors { kCtap2ErrPinInvalid, kCtap2ErrPinBlocked, kCtap2ErrPinAuthInvalid, kCtap2ErrPinAuthBlocked }
+        during 1) GetPinToken or 2) MakeCredential/GetAssertion with PinAuth.
+
+        All errors should be reported to the client so that appropriate UI can be displayed to users.
+        For kCtap2ErrPinAuthInvalid and kCtap2ErrPinInvalid, we will restart the whole Pin process to get
+        another Pin from the user.
+
+        Covered by API tests.
+
+        * UIProcess/API/APIWebAuthenticationPanelClient.h:
+        * UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm:
+        (WebKit::wkWebAuthenticationPanelUpdate):
+        * UIProcess/WebAuthentication/WebAuthenticationFlags.h:
+        * UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:
+        (WebKit::fido::toStatus):
+        (WebKit::fido::isPinError):
+        (WebKit::CtapAuthenticator::continueMakeCredentialAfterResponseReceived):
+        (WebKit::CtapAuthenticator::continueGetAssertionAfterResponseReceived):
+        (WebKit::CtapAuthenticator::continueRequestAfterGetPinToken):
+        (WebKit::CtapAuthenticator::tryRestartPin):
+        * UIProcess/WebAuthentication/fido/CtapAuthenticator.h:
+
 2020-02-07  Jonathan Bedard  <[email protected]>
 
         Handle deprecated APIs in WKImagePreviewViewController

Modified: trunk/Source/WebKit/UIProcess/API/APIWebAuthenticationPanelClient.h (256061 => 256062)


--- trunk/Source/WebKit/UIProcess/API/APIWebAuthenticationPanelClient.h	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Source/WebKit/UIProcess/API/APIWebAuthenticationPanelClient.h	2020-02-07 22:16:54 UTC (rev 256062)
@@ -37,7 +37,7 @@
 }
 
 namespace WebKit {
-enum class WebAuthenticationStatus : bool;
+enum class WebAuthenticationStatus : uint8_t;
 enum class WebAuthenticationResult : bool;
 }
 

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm (256061 => 256062)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm	2020-02-07 22:16:54 UTC (rev 256062)
@@ -59,6 +59,12 @@
         return _WKWebAuthenticationPanelUpdateMultipleNFCTagsPresent;
     if (status == WebAuthenticationStatus::NoCredentialsFound)
         return _WKWebAuthenticationPanelUpdateNoCredentialsFound;
+    if (status == WebAuthenticationStatus::PinBlocked)
+        return _WKWebAuthenticationPanelUpdatePINBlocked;
+    if (status == WebAuthenticationStatus::PinAuthBlocked)
+        return _WKWebAuthenticationPanelUpdatePINAuthBlocked;
+    if (status == WebAuthenticationStatus::PinInvalid)
+        return _WKWebAuthenticationPanelUpdatePINInvalid;
     ASSERT_NOT_REACHED();
     return _WKWebAuthenticationPanelUpdateMultipleNFCTagsPresent;
 }

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationFlags.h (256061 => 256062)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationFlags.h	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationFlags.h	2020-02-07 22:16:54 UTC (rev 256062)
@@ -40,9 +40,12 @@
     Failed
 };
 
-enum class WebAuthenticationStatus : bool {
+enum class WebAuthenticationStatus : uint8_t {
     MultipleNFCTagsPresent,
-    NoCredentialsFound
+    NoCredentialsFound,
+    PinBlocked,
+    PinAuthBlocked,
+    PinInvalid
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp (256061 => 256062)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp	2020-02-07 22:16:54 UTC (rev 256062)
@@ -46,6 +46,38 @@
 using namespace WebCore;
 using namespace fido;
 
+namespace {
+WebAuthenticationStatus toStatus(const CtapDeviceResponseCode& error)
+{
+    switch (error) {
+    case CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid:
+    case CtapDeviceResponseCode::kCtap2ErrPinInvalid:
+        return WebAuthenticationStatus::PinInvalid;
+    case CtapDeviceResponseCode::kCtap2ErrPinAuthBlocked:
+        return WebAuthenticationStatus::PinAuthBlocked;
+    case CtapDeviceResponseCode::kCtap2ErrPinBlocked:
+        return WebAuthenticationStatus::PinBlocked;
+    default:
+        ASSERT_NOT_REACHED();
+        return WebAuthenticationStatus::PinInvalid;
+    }
+}
+
+bool isPinError(const CtapDeviceResponseCode& error)
+{
+    switch (error) {
+    case CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid:
+    case CtapDeviceResponseCode::kCtap2ErrPinAuthBlocked:
+    case CtapDeviceResponseCode::kCtap2ErrPinInvalid:
+    case CtapDeviceResponseCode::kCtap2ErrPinBlocked:
+        return true;
+    default:
+        return false;
+    }
+}
+
+} // namespace
+
 CtapAuthenticator::CtapAuthenticator(std::unique_ptr<CtapDriver>&& driver, AuthenticatorGetInfoResponse&& info)
     : FidoAuthenticator(WTFMove(driver))
     , m_info(WTFMove(info))
@@ -76,13 +108,20 @@
     auto response = readCTAPMakeCredentialResponse(data, WTF::get<PublicKeyCredentialCreationOptions>(requestData().options).attestation);
     if (!response) {
         auto error = getResponseCode(data);
-        if (error == CtapDeviceResponseCode::kCtap2ErrCredentialExcluded)
+
+        if (error == CtapDeviceResponseCode::kCtap2ErrCredentialExcluded) {
             receiveRespond(ExceptionData { InvalidStateError, "At least one credential matches an entry of the excludeCredentials list in the authenticator."_s });
-        // FIXME(205837)
-        else if (error == CtapDeviceResponseCode::kCtap2ErrPinInvalid || error == CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid)
-            getRetries();
-        else
-            receiveRespond(ExceptionData { UnknownError, makeString("Unknown internal error. Error code: ", static_cast<uint8_t>(error)) });
+            return;
+        }
+
+        if (isPinError(error)) {
+            if (!m_pinAuth.isEmpty()) // Skip the very first command that acts like wink.
+                observer()->authenticatorStatusUpdated(toStatus(error));
+            if (tryRestartPin(error))
+                return;
+        }
+
+        receiveRespond(ExceptionData { UnknownError, makeString("Unknown internal error. Error code: ", static_cast<uint8_t>(error)) });
         return;
     }
     receiveRespond(response.releaseNonNull());
@@ -110,15 +149,20 @@
     auto response = readCTAPGetAssertionResponse(data);
     if (!response) {
         auto error = getResponseCode(data);
-        // FIXME(205837)
-        if (error == CtapDeviceResponseCode::kCtap2ErrPinInvalid || error == CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid) {
-            getRetries();
+
+        if (!isPinError(error) && tryDowngrade())
             return;
+
+        if (isPinError(error)) {
+            if (!m_pinAuth.isEmpty()) // Skip the very first command that acts like wink.
+                observer()->authenticatorStatusUpdated(toStatus(error));
+            if (tryRestartPin(error))
+                return;
         }
-        if (error != CtapDeviceResponseCode::kCtap2ErrInvalidCBOR && tryDowngrade())
-            return;
+
         if (error == CtapDeviceResponseCode::kCtap2ErrNoCredentials && observer())
             observer()->authenticatorStatusUpdated(WebAuthenticationStatus::NoCredentialsFound);
+
         receiveRespond(ExceptionData { UnknownError, makeString("Unknown internal error. Error code: ", static_cast<uint8_t>(error)) });
         return;
     }
@@ -249,6 +293,13 @@
     auto token = pin::TokenResponse::parse(tokenRequest.sharedKey(), data);
     if (!token) {
         auto error = getResponseCode(data);
+
+        if (isPinError(error)) {
+            observer()->authenticatorStatusUpdated(toStatus(error));
+            if (tryRestartPin(error))
+                return;
+        }
+
         receiveRespond(ExceptionData { UnknownError, makeString("Unknown internal error. Error code: ", static_cast<uint8_t>(error)) });
         return;
     }
@@ -261,6 +312,18 @@
     });
 }
 
+bool CtapAuthenticator::tryRestartPin(const CtapDeviceResponseCode& error)
+{
+    switch (error) {
+    case CtapDeviceResponseCode::kCtap2ErrPinAuthInvalid:
+    case CtapDeviceResponseCode::kCtap2ErrPinInvalid:
+        getRetries();
+        return true;
+    default:
+        return false;
+    }
+}
+
 bool CtapAuthenticator::tryDowngrade()
 {
     if (m_info.versions().find(ProtocolVersion::kU2f) == m_info.versions().end())

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.h (256061 => 256062)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.h	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.h	2020-02-07 22:16:54 UTC (rev 256062)
@@ -65,6 +65,7 @@
     void continueRequestPinAfterGetKeyAgreement(Vector<uint8_t>&&, uint64_t retries);
     void continueGetPinTokenAfterRequestPin(const String& pin, const WebCore::CryptoKeyEC&);
     void continueRequestAfterGetPinToken(Vector<uint8_t>&&, const fido::pin::TokenRequest&);
+    bool tryRestartPin(const fido::CtapDeviceResponseCode&);
 
     bool tryDowngrade();
     bool processGoogleLegacyAppIdSupportExtension();

Modified: trunk/Tools/ChangeLog (256061 => 256062)


--- trunk/Tools/ChangeLog	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Tools/ChangeLog	2020-02-07 22:16:54 UTC (rev 256062)
@@ -1,3 +1,24 @@
+2020-02-07  Jiewen Tan  <[email protected]>
+
+        [WebAuthn] Report CTAP Client Pin Error to clients
+        https://bugs.webkit.org/show_bug.cgi?id=205837
+        <rdar://problem/58356872>
+
+        Reviewed by Brent Fulgham.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
+        (-[TestWebAuthenticationPanelDelegate panel:updateWebAuthenticationPanel:]):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-auth-blocked-error.html: Copied from Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html.
+        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-invalid-error-retry.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-auth-blocked-error.html: Copied from Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html.
+        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html: Copied from Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html.
+        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html: Renamed from Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html.
+        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-invalid-error-retry.html: Added.
+
 2020-02-07  Jonathan Bedard  <[email protected]>
 
         run-safari Doesn't work with the latest Xcode version and iOS

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (256061 => 256062)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-02-07 22:16:54 UTC (rev 256062)
@@ -333,7 +333,7 @@
 		55F9D2E52205031800A9AB38 /* AdditionalSupportedImageTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 55F9D2E42205031800A9AB38 /* AdditionalSupportedImageTypes.mm */; };
 		570D26F423C3CA6A00D5CF67 /* web-authentication-make-credential-hid-pin-get-key-agreement-error.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 570D26F323C3CA5500D5CF67 /* web-authentication-make-credential-hid-pin-get-key-agreement-error.html */; };
 		570D26F623C3D33000D5CF67 /* web-authentication-make-credential-hid-pin.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 570D26F523C3D32700D5CF67 /* web-authentication-make-credential-hid-pin.html */; };
-		570D26FA23C3F25100D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-error.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 570D26F923C3F24500D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-error.html */; };
+		570D26FA23C3F25100D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 570D26F923C3F24500D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html */; };
 		570D26FC23C3F87000D5CF67 /* web-authentication-get-assertion-hid-pin.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 570D26FB23C3F86500D5CF67 /* web-authentication-get-assertion-hid-pin.html */; };
 		5714ECB91CA8B5B000051AC8 /* DownloadRequestOriginalURL.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5714ECB81CA8B58800051AC8 /* DownloadRequestOriginalURL.html */; };
 		5714ECBB1CA8BFE400051AC8 /* DownloadRequestOriginalURLFrame.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5714ECBA1CA8BFD100051AC8 /* DownloadRequestOriginalURLFrame.html */; };
@@ -366,6 +366,13 @@
 		5774AA6821FBBF7800AF2A1B /* TestSOAuthorization.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5774AA6721FBBF7800AF2A1B /* TestSOAuthorization.mm */; };
 		5778D05622110A2600899E3B /* LoadWebArchive.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5778D05522110A2600899E3B /* LoadWebArchive.mm */; };
 		578CBD67204FB2C80083B9F2 /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 578CBD66204FB2C70083B9F2 /* LocalAuthentication.framework */; };
+		578DA44223ECC7A000246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 578DA44123ECC76B00246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html */; };
+		578DA44423ECCAE900246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 578DA44323ECC8A800246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html */; };
+		578DA44623ECCC0A00246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 578DA44523ECCBD000246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html */; };
+		578DA44823ECD09B00246010 /* web-authentication-make-credential-hid-pin-auth-blocked-error.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 578DA44723ECD01300246010 /* web-authentication-make-credential-hid-pin-auth-blocked-error.html */; };
+		578DA44A23ECD18600246010 /* web-authentication-make-credential-hid-pin-invalid-error-retry.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 578DA44923ECD15500246010 /* web-authentication-make-credential-hid-pin-invalid-error-retry.html */; };
+		578DA44C23ECD23000246010 /* web-authentication-get-assertion-hid-pin-auth-blocked-error.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 578DA44B23ECD20300246010 /* web-authentication-get-assertion-hid-pin-auth-blocked-error.html */; };
+		578DA44E23ECD28B00246010 /* web-authentication-get-assertion-hid-pin-invalid-error-retry.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 578DA44D23ECD26100246010 /* web-authentication-get-assertion-hid-pin-invalid-error-retry.html */; };
 		57901FB11CAF142D00ED64F9 /* LoadInvalidURLRequest.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57901FB01CAF141C00ED64F9 /* LoadInvalidURLRequest.html */; };
 		579651E7216BFDED006EBFE5 /* FidoHidMessageTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 579651E6216BFD53006EBFE5 /* FidoHidMessageTest.cpp */; };
 		5797FE311EB15A6800B2F4A0 /* NavigationClientDefaultCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5797FE2F1EB15A5F00B2F4A0 /* NavigationClientDefaultCrypto.cpp */; };
@@ -1501,6 +1508,8 @@
 				57663DF32357E48900E85E09 /* web-authentication-get-assertion-hid-cancel.html in Copy Resources */,
 				579F1C0123C93AF500C7D4B4 /* web-authentication-get-assertion-hid-multiple-accounts.html in Copy Resources */,
 				577454D02359B378008E1ED7 /* web-authentication-get-assertion-hid-no-credentials.html in Copy Resources */,
+				578DA44C23ECD23000246010 /* web-authentication-get-assertion-hid-pin-auth-blocked-error.html in Copy Resources */,
+				578DA44E23ECD28B00246010 /* web-authentication-get-assertion-hid-pin-invalid-error-retry.html in Copy Resources */,
 				570D26FC23C3F87000D5CF67 /* web-authentication-get-assertion-hid-pin.html in Copy Resources */,
 				57663DEC234F1F9300E85E09 /* web-authentication-get-assertion-hid.html in Copy Resources */,
 				579833922368FA37008E5547 /* web-authentication-get-assertion-nfc-multiple-tags.html in Copy Resources */,
@@ -1507,9 +1516,14 @@
 				57663DEA234EA66D00E85E09 /* web-authentication-get-assertion-nfc.html in Copy Resources */,
 				577454D22359BB01008E1ED7 /* web-authentication-get-assertion-u2f-no-credentials.html in Copy Resources */,
 				57C624502346C21E00383FE7 /* web-authentication-get-assertion.html in Copy Resources */,
+				578DA44823ECD09B00246010 /* web-authentication-make-credential-hid-pin-auth-blocked-error.html in Copy Resources */,
 				570D26F423C3CA6A00D5CF67 /* web-authentication-make-credential-hid-pin-get-key-agreement-error.html in Copy Resources */,
-				570D26FA23C3F25100D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-error.html in Copy Resources */,
+				578DA44223ECC7A000246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html in Copy Resources */,
+				578DA44623ECCC0A00246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html in Copy Resources */,
+				570D26FA23C3F25100D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html in Copy Resources */,
+				578DA44423ECCAE900246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html in Copy Resources */,
 				5758598423C3C3A400C74572 /* web-authentication-make-credential-hid-pin-get-retries-error.html in Copy Resources */,
+				578DA44A23ECD18600246010 /* web-authentication-make-credential-hid-pin-invalid-error-retry.html in Copy Resources */,
 				570D26F623C3D33000D5CF67 /* web-authentication-make-credential-hid-pin.html in Copy Resources */,
 				5798337E236019A4008E5547 /* web-authentication-make-credential-hid.html in Copy Resources */,
 				1C2B81861C89259D00A5529F /* webfont.html in Copy Resources */,
@@ -1925,7 +1939,7 @@
 		55F9D2E42205031800A9AB38 /* AdditionalSupportedImageTypes.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = AdditionalSupportedImageTypes.mm; sourceTree = "<group>"; };
 		570D26F323C3CA5500D5CF67 /* web-authentication-make-credential-hid-pin-get-key-agreement-error.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin-get-key-agreement-error.html"; sourceTree = "<group>"; };
 		570D26F523C3D32700D5CF67 /* web-authentication-make-credential-hid-pin.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin.html"; sourceTree = "<group>"; };
-		570D26F923C3F24500D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-error.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin-get-pin-token-error.html"; sourceTree = "<group>"; };
+		570D26F923C3F24500D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html"; sourceTree = "<group>"; };
 		570D26FB23C3F86500D5CF67 /* web-authentication-get-assertion-hid-pin.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-get-assertion-hid-pin.html"; sourceTree = "<group>"; };
 		5714ECB81CA8B58800051AC8 /* DownloadRequestOriginalURL.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DownloadRequestOriginalURL.html; sourceTree = "<group>"; };
 		5714ECBA1CA8BFD100051AC8 /* DownloadRequestOriginalURLFrame.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DownloadRequestOriginalURLFrame.html; sourceTree = "<group>"; };
@@ -1960,6 +1974,13 @@
 		5774AA6721FBBF7800AF2A1B /* TestSOAuthorization.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestSOAuthorization.mm; sourceTree = "<group>"; };
 		5778D05522110A2600899E3B /* LoadWebArchive.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LoadWebArchive.mm; sourceTree = "<group>"; };
 		578CBD66204FB2C70083B9F2 /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = System/Library/Frameworks/LocalAuthentication.framework; sourceTree = SDKROOT; };
+		578DA44123ECC76B00246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html"; sourceTree = "<group>"; };
+		578DA44323ECC8A800246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html"; sourceTree = "<group>"; };
+		578DA44523ECCBD000246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html"; sourceTree = "<group>"; };
+		578DA44723ECD01300246010 /* web-authentication-make-credential-hid-pin-auth-blocked-error.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin-auth-blocked-error.html"; sourceTree = "<group>"; };
+		578DA44923ECD15500246010 /* web-authentication-make-credential-hid-pin-invalid-error-retry.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin-invalid-error-retry.html"; sourceTree = "<group>"; };
+		578DA44B23ECD20300246010 /* web-authentication-get-assertion-hid-pin-auth-blocked-error.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-get-assertion-hid-pin-auth-blocked-error.html"; sourceTree = "<group>"; };
+		578DA44D23ECD26100246010 /* web-authentication-get-assertion-hid-pin-invalid-error-retry.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-get-assertion-hid-pin-invalid-error-retry.html"; sourceTree = "<group>"; };
 		57901FAC1CAF12C200ED64F9 /* LoadInvalidURLRequest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LoadInvalidURLRequest.mm; sourceTree = "<group>"; };
 		57901FAE1CAF137100ED64F9 /* LoadInvalidURLRequest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LoadInvalidURLRequest.mm; sourceTree = "<group>"; };
 		57901FB01CAF141C00ED64F9 /* LoadInvalidURLRequest.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LoadInvalidURLRequest.html; sourceTree = "<group>"; };
@@ -3538,6 +3559,8 @@
 				57663DF22357E45D00E85E09 /* web-authentication-get-assertion-hid-cancel.html */,
 				579F1BFF23C92FD300C7D4B4 /* web-authentication-get-assertion-hid-multiple-accounts.html */,
 				577454CF2359B338008E1ED7 /* web-authentication-get-assertion-hid-no-credentials.html */,
+				578DA44B23ECD20300246010 /* web-authentication-get-assertion-hid-pin-auth-blocked-error.html */,
+				578DA44D23ECD26100246010 /* web-authentication-get-assertion-hid-pin-invalid-error-retry.html */,
 				570D26FB23C3F86500D5CF67 /* web-authentication-get-assertion-hid-pin.html */,
 				57663DEB234F1F8000E85E09 /* web-authentication-get-assertion-hid.html */,
 				5798337B235EB65C008E5547 /* web-authentication-get-assertion-nfc-multiple-tags.html */,
@@ -3544,9 +3567,14 @@
 				57663DE9234EA60B00E85E09 /* web-authentication-get-assertion-nfc.html */,
 				577454D12359BAD5008E1ED7 /* web-authentication-get-assertion-u2f-no-credentials.html */,
 				57C6244F2346C1EC00383FE7 /* web-authentication-get-assertion.html */,
+				578DA44723ECD01300246010 /* web-authentication-make-credential-hid-pin-auth-blocked-error.html */,
 				570D26F323C3CA5500D5CF67 /* web-authentication-make-credential-hid-pin-get-key-agreement-error.html */,
-				570D26F923C3F24500D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-error.html */,
+				578DA44123ECC76B00246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html */,
+				578DA44523ECCBD000246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html */,
+				570D26F923C3F24500D5CF67 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html */,
+				578DA44323ECC8A800246010 /* web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html */,
 				5758598323C3C36200C74572 /* web-authentication-make-credential-hid-pin-get-retries-error.html */,
+				578DA44923ECD15500246010 /* web-authentication-make-credential-hid-pin-invalid-error-retry.html */,
 				570D26F523C3D32700D5CF67 /* web-authentication-make-credential-hid-pin.html */,
 				5798337D2360196D008E5547 /* web-authentication-make-credential-hid.html */,
 				51714EB21CF8C761004723C4 /* WebProcessKillIDBCleanup-1.html */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm (256061 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm	2020-02-07 22:16:54 UTC (rev 256062)
@@ -46,6 +46,9 @@
 static bool webAuthenticationPanelSucceded = false;
 static bool webAuthenticationPanelUpdateMultipleNFCTagsPresent = false;
 static bool webAuthenticationPanelUpdateNoCredentialsFound = false;
+static bool webAuthenticationPanelUpdatePINBlocked = false;
+static bool webAuthenticationPanelUpdatePINAuthBlocked = false;
+static bool webAuthenticationPanelUpdatePINInvalid = false;
 static bool webAuthenticationPanelCancelImmediately = false;
 static String webAuthenticationPanelPin;
 static BOOL webAuthenticationPanelNullUserHandle = NO;
@@ -69,6 +72,18 @@
         webAuthenticationPanelUpdateNoCredentialsFound = true;
         return;
     }
+    if (update == _WKWebAuthenticationPanelUpdatePINBlocked) {
+        webAuthenticationPanelUpdatePINBlocked = true;
+        return;
+    }
+    if (update == _WKWebAuthenticationPanelUpdatePINAuthBlocked) {
+        webAuthenticationPanelUpdatePINAuthBlocked = true;
+        return;
+    }
+    if (update == _WKWebAuthenticationPanelUpdatePINInvalid) {
+        webAuthenticationPanelUpdatePINInvalid = true;
+        return;
+    }
 }
 
 - (void)panel:(_WKWebAuthenticationPanel *)panel dismissWebAuthenticationPanelWithResult:(_WKWebAuthenticationResult)result
@@ -221,7 +236,14 @@
     webAuthenticationPanelRan = false;
     webAuthenticationPanelFailed = false;
     webAuthenticationPanelSucceded = false;
+    webAuthenticationPanelUpdateMultipleNFCTagsPresent = false;
+    webAuthenticationPanelUpdateNoCredentialsFound = false;
+    webAuthenticationPanelUpdatePINBlocked = false;
+    webAuthenticationPanelUpdatePINAuthBlocked = false;
+    webAuthenticationPanelUpdatePINInvalid = false;
     webAuthenticationPanelCancelImmediately = false;
+    webAuthenticationPanelPin = emptyString();
+    webAuthenticationPanelNullUserHandle = NO;
 }
 
 static void checkPanel(_WKWebAuthenticationPanel *panel, NSString *relyingPartyID, NSArray *transports, _WKWebAuthenticationType type)
@@ -838,10 +860,10 @@
     [webView waitForMessage:@"Pin is not valid: 123"];
 }
 
-TEST(WebAuthenticationPanel, PinGetPinTokenError)
+TEST(WebAuthenticationPanel, PinGetPinTokenPinBlockedError)
 {
     reset();
-    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-hid-pin-get-pin-token-error" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
 
     auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
     [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
@@ -852,9 +874,66 @@
 
     webAuthenticationPanelPin = "1234";
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
-    [webView waitForMessage:@"Unknown internal error. Error code: 2"];
+    [webView waitForMessage:@"Unknown internal error. Error code: 50"];
+    EXPECT_FALSE(webAuthenticationPanelUpdatePINInvalid);
+    EXPECT_TRUE(webAuthenticationPanelUpdatePINBlocked);
 }
 
+TEST(WebAuthenticationPanel, PinGetPinTokenPinAuthBlockedError)
+{
+    reset();
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
+    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
+    [webView setUIDelegate:delegate.get()];
+
+    webAuthenticationPanelPin = "1234";
+    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
+    [webView waitForMessage:@"Unknown internal error. Error code: 52"];
+    EXPECT_FALSE(webAuthenticationPanelUpdatePINInvalid);
+    EXPECT_TRUE(webAuthenticationPanelUpdatePINAuthBlocked);
+}
+
+TEST(WebAuthenticationPanel, PinGetPinTokenPinInvalidErrorAndRetry)
+{
+    reset();
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
+    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
+    [webView setUIDelegate:delegate.get()];
+
+    webAuthenticationPanelPin = "1234";
+    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
+    [webView waitForMessage:@"Succeeded!"];
+    EXPECT_TRUE(webAuthenticationPanelUpdatePINInvalid);
+}
+
+TEST(WebAuthenticationPanel, PinGetPinTokenPinAuthInvalidErrorAndRetry)
+{
+    reset();
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
+    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
+    [webView setUIDelegate:delegate.get()];
+
+    webAuthenticationPanelPin = "1234";
+    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
+    [webView waitForMessage:@"Succeeded!"];
+    EXPECT_TRUE(webAuthenticationPanelUpdatePINInvalid);
+}
+
 TEST(WebAuthenticationPanel, MakeCredentialPin)
 {
     reset();
@@ -872,6 +951,43 @@
     [webView waitForMessage:@"Succeeded!"];
 }
 
+TEST(WebAuthenticationPanel, MakeCredentialPinAuthBlockedError)
+{
+    reset();
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-hid-pin-auth-blocked-error" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
+    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
+    [webView setUIDelegate:delegate.get()];
+
+    webAuthenticationPanelPin = "1234";
+    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
+    [webView waitForMessage:@"Unknown internal error. Error code: 52"];
+    EXPECT_FALSE(webAuthenticationPanelUpdatePINInvalid);
+    EXPECT_TRUE(webAuthenticationPanelUpdatePINAuthBlocked);
+}
+
+TEST(WebAuthenticationPanel, MakeCredentialPinInvalidErrorAndRetry)
+{
+    reset();
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-hid-pin-invalid-error-retry" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
+    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
+    [webView setUIDelegate:delegate.get()];
+
+    webAuthenticationPanelPin = "1234";
+    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
+    [webView waitForMessage:@"Succeeded!"];
+    EXPECT_TRUE(webAuthenticationPanelUpdatePINInvalid);
+}
+
 TEST(WebAuthenticationPanel, GetAssertionPin)
 {
     reset();
@@ -889,6 +1005,43 @@
     [webView waitForMessage:@"Succeeded!"];
 }
 
+TEST(WebAuthenticationPanel, GetAssertionPinAuthBlockedError)
+{
+    reset();
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-get-assertion-hid-pin-auth-blocked-error" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
+    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
+    [webView setUIDelegate:delegate.get()];
+
+    webAuthenticationPanelPin = "1234";
+    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
+    [webView waitForMessage:@"Unknown internal error. Error code: 52"];
+    EXPECT_FALSE(webAuthenticationPanelUpdatePINInvalid);
+    EXPECT_TRUE(webAuthenticationPanelUpdatePINAuthBlocked);
+}
+
+TEST(WebAuthenticationPanel, GetAssertionPinInvalidErrorAndRetry)
+{
+    reset();
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-get-assertion-hid-pin-invalid-error-retry" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
+    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
+    [webView setUIDelegate:delegate.get()];
+
+    webAuthenticationPanelPin = "1234";
+    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
+    [webView waitForMessage:@"Succeeded!"];
+    EXPECT_TRUE(webAuthenticationPanelUpdatePINInvalid);
+}
+
 TEST(WebAuthenticationPanel, MultipleAccountsNullDelegate)
 {
     reset();

Copied: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-auth-blocked-error.html (from rev 256060, trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html) (0 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-auth-blocked-error.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-auth-blocked-error.html	2020-02-07 22:16:54 UTC (rev 256062)
@@ -0,0 +1,27 @@
+<input type="text" id="input">
+<script>
+    const testCtapPinAuthInvalidErrorBase64 = "Mw==";
+    const testPinGetRetriesResponseBase64 = "AKEDCA==";
+    const testPinGetKeyAgreementResponseBase64 = "AKEBpQECAzgYIAEhWCDodiWJbuTkbcAydm6Ah5YvNt+d/otWfzdjAVsZkKYOFCJYICfeYS1mQYvaGVBYHrxcjB2tcQyxTCL4yXBF9GEvsgyR";
+    const testPinGetPinTokenResponseBase64 = "AKECUBOk7rcOyRrqAB6TFvYeQfc=";
+    const testCtapPinAuthBlockedErrorBase64 = "NA==";
+    if (window.internals) {
+        internals.setMockWebAuthenticationConfiguration({ hid: { supportClientPin: true, payloadBase64: [testCtapPinAuthInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testPinGetPinTokenResponseBase64, testCtapPinAuthBlockedErrorBase64] } });
+        internals.withUserGesture(() => { input.focus(); });
+    }
+
+    const options = {
+        publicKey: {
+            challenge: new Uint8Array(16),
+            timeout: 100
+        }
+    };
+
+    navigator.credentials.get(options).then(credential => {
+        // console.log("Succeeded!");
+        window.webkit.messageHandlers.testHandler.postMessage("Succeeded!");
+    }, error => {
+        // console.log(error.message);
+        window.webkit.messageHandlers.testHandler.postMessage(error.message);
+    });
+</script>

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-invalid-error-retry.html (0 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-invalid-error-retry.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-hid-pin-invalid-error-retry.html	2020-02-07 22:16:54 UTC (rev 256062)
@@ -0,0 +1,32 @@
+<input type="text" id="input">
+<script>
+    const testCtapPinAuthInvalidErrorBase64 = "Mw==";
+    const testPinGetRetriesResponseBase64 = "AKEDCA==";
+    const testPinGetKeyAgreementResponseBase64 = "AKEBpQECAzgYIAEhWCDodiWJbuTkbcAydm6Ah5YvNt+d/otWfzdjAVsZkKYOFCJYICfeYS1mQYvaGVBYHrxcjB2tcQyxTCL4yXBF9GEvsgyR";
+    const testPinGetPinTokenResponseBase64 = "AKECUBOk7rcOyRrqAB6TFvYeQfc=";
+    const testAssertionMessageBase64 =
+        "AKMBomJpZFhAKAitzuj+Tslzelf3/vZwIGtDQNgoKeFd5oEieYzhyzA65saf0tK2" +
+        "w/mooa7tQtGgDdwZIjOhjcuZ0pQ1ajoE4GR0eXBlanB1YmxpYy1rZXkCWCVGzH+5" +
+        "Z51VstuQkuHI2eXh0Ct1gPC0gSx3CWLh5I9a2AEAAABQA1hHMEUCIQCSFTuuBWgB" +
+        "4/F0VB7DlUVM09IHPmxe1MzHUwRoCRZbCAIgGKov6xoAx2MEf6/6qNs8OutzhP2C" +
+        "QoJ1L7Fe64G9uBc=";
+    if (window.internals) {
+        internals.setMockWebAuthenticationConfiguration({ hid: { supportClientPin: true, payloadBase64: [testCtapPinAuthInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testPinGetPinTokenResponseBase64, testCtapPinAuthInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testPinGetPinTokenResponseBase64, testAssertionMessageBase64] } });
+        internals.withUserGesture(() => { input.focus(); });
+    }
+
+    const options = {
+        publicKey: {
+            challenge: new Uint8Array(16),
+            timeout: 100
+        }
+    };
+
+    navigator.credentials.get(options).then(credential => {
+        // console.log("Succeeded!");
+        window.webkit.messageHandlers.testHandler.postMessage("Succeeded!");
+    }, error => {
+        // console.log(error.message);
+        window.webkit.messageHandlers.testHandler.postMessage(error.message);
+    });
+</script>

Copied: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-auth-blocked-error.html (from rev 256060, trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html) (0 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-auth-blocked-error.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-auth-blocked-error.html	2020-02-07 22:16:54 UTC (rev 256062)
@@ -0,0 +1,35 @@
+<input type="text" id="input">
+<script>
+    const testCtapPinAuthInvalidErrorBase64 = "Mw==";
+    const testPinGetRetriesResponseBase64 = "AKEDCA==";
+    const testPinGetKeyAgreementResponseBase64 = "AKEBpQECAzgYIAEhWCDodiWJbuTkbcAydm6Ah5YvNt+d/otWfzdjAVsZkKYOFCJYICfeYS1mQYvaGVBYHrxcjB2tcQyxTCL4yXBF9GEvsgyR";
+    const testPinGetPinTokenResponseBase64 = "AKECUBOk7rcOyRrqAB6TFvYeQfc=";
+    const testCtapPinAuthBlockedErrorBase64 = "NA==";
+    if (window.internals) {
+        internals.setMockWebAuthenticationConfiguration({ hid: { supportClientPin: true, payloadBase64: [testCtapPinAuthInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testPinGetPinTokenResponseBase64, testCtapPinAuthBlockedErrorBase64, ] } });
+        internals.withUserGesture(() => { input.focus(); });
+    }
+
+    const options = {
+        publicKey: {
+            rp: {
+                name: "localhost",
+            },
+            user: {
+                name: "John Appleseed",
+                id: new Uint8Array(16),
+                displayName: "Appleseed",
+            },
+            challenge: new Uint8Array(16),
+            pubKeyCredParams: [{ type: "public-key", alg: -7 }]
+        }
+    };
+
+    navigator.credentials.create(options).then(credential => {
+        // console.log("Succeeded!");
+        window.webkit.messageHandlers.testHandler.postMessage("Succeeded!");
+    }, error => {
+        // console.log(error.message);
+        window.webkit.messageHandlers.testHandler.postMessage(error.message);
+    });
+</script>

Deleted: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html (256061 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html	2020-02-07 22:08:25 UTC (rev 256061)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html	2020-02-07 22:16:54 UTC (rev 256062)
@@ -1,34 +0,0 @@
-<input type="text" id="input">
-<script>
-    const testCtapPinInvalidErrorBase64 = "MQ==";
-    const testPinGetRetriesResponseBase64 = "AKEDCA==";
-    const testPinGetKeyAgreementResponseBase64 = "AKEBpQECAzgYIAEhWCDodiWJbuTkbcAydm6Ah5YvNt+d/otWfzdjAVsZkKYOFCJYICfeYS1mQYvaGVBYHrxcjB2tcQyxTCL4yXBF9GEvsgyR";
-    const testCtapInvalidParameterErrorBase64 = "Ag==";
-    if (window.internals) {
-        internals.setMockWebAuthenticationConfiguration({ hid: { supportClientPin: true, payloadBase64: [testCtapPinInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testCtapInvalidParameterErrorBase64] } });
-        internals.withUserGesture(() => { input.focus(); });
-    }
-
-    const options = {
-        publicKey: {
-            rp: {
-                name: "localhost",
-            },
-            user: {
-                name: "John Appleseed",
-                id: new Uint8Array(16),
-                displayName: "Appleseed",
-            },
-            challenge: new Uint8Array(16),
-            pubKeyCredParams: [{ type: "public-key", alg: -7 }]
-        }
-    };
-
-    navigator.credentials.create(options).then(credential => {
-        // console.log("Succeeded!");
-        window.webkit.messageHandlers.testHandler.postMessage("Succeeded!");
-    }, error => {
-        // console.log(error.message);
-        window.webkit.messageHandlers.testHandler.postMessage(error.message);
-    });
-</script>

Copied: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html (from rev 256060, trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html) (0 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-blocked-error.html	2020-02-07 22:16:54 UTC (rev 256062)
@@ -0,0 +1,34 @@
+<input type="text" id="input">
+<script>
+    const testCtapPinInvalidErrorBase64 = "MQ==";
+    const testPinGetRetriesResponseBase64 = "AKEDCA==";
+    const testPinGetKeyAgreementResponseBase64 = "AKEBpQECAzgYIAEhWCDodiWJbuTkbcAydm6Ah5YvNt+d/otWfzdjAVsZkKYOFCJYICfeYS1mQYvaGVBYHrxcjB2tcQyxTCL4yXBF9GEvsgyR";
+    const testCtapPinAuthBlockedErrorBase64 = "NA==";
+    if (window.internals) {
+        internals.setMockWebAuthenticationConfiguration({ hid: { supportClientPin: true, payloadBase64: [testCtapPinInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testCtapPinAuthBlockedErrorBase64] } });
+        internals.withUserGesture(() => { input.focus(); });
+    }
+
+    const options = {
+        publicKey: {
+            rp: {
+                name: "localhost",
+            },
+            user: {
+                name: "John Appleseed",
+                id: new Uint8Array(16),
+                displayName: "Appleseed",
+            },
+            challenge: new Uint8Array(16),
+            pubKeyCredParams: [{ type: "public-key", alg: -7 }]
+        }
+    };
+
+    navigator.credentials.create(options).then(credential => {
+        // console.log("Succeeded!");
+        window.webkit.messageHandlers.testHandler.postMessage("Succeeded!");
+    }, error => {
+        // console.log(error.message);
+        window.webkit.messageHandlers.testHandler.postMessage(error.message);
+    });
+</script>

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html (0 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-auth-invalid-error-retry.html	2020-02-07 22:16:54 UTC (rev 256062)
@@ -0,0 +1,57 @@
+<input type="text" id="input">
+<script>
+    const testCtapPinInvalidErrorBase64 = "MQ==";
+    const testPinGetRetriesResponseBase64 = "AKEDCA==";
+    const testPinGetKeyAgreementResponseBase64 = "AKEBpQECAzgYIAEhWCDodiWJbuTkbcAydm6Ah5YvNt+d/otWfzdjAVsZkKYOFCJYICfeYS1mQYvaGVBYHrxcjB2tcQyxTCL4yXBF9GEvsgyR";
+    const testPinGetPinTokenResponseBase64 = "AKECUBOk7rcOyRrqAB6TFvYeQfc=";
+    const testCreationMessageBase64 =
+        "AKMBZnBhY2tlZAJYxEbMf7lnnVWy25CS4cjZ5eHQK3WA8LSBLHcJYuHkj1rYQQAA" +
+        "AE74oBHzjApNFYAGFxEfntx9AEAoCK3O6P5OyXN6V/f+9nAga0NA2Cgp4V3mgSJ5" +
+        "jOHLMDrmxp/S0rbD+aihru1C0aAN3BkiM6GNy5nSlDVqOgTgpQECAyYgASFYIEFb" +
+        "he3RkNud6sgyraBGjlh1pzTlCZehQlL/b18HZ6WGIlggJgfUd/en9p5AIqMQbUni" +
+        "nEeXdFLkvW0/zV5BpEjjNxADo2NhbGcmY3NpZ1hHMEUCIQDKg+ZBmEBtf0lWq4Re" +
+        "dH4/i/LOYqOR4uR2NAj2zQmw9QIgbTXb4hvFbj4T27bv/rGrc+y+0puoYOBkBk9P" +
+        "mCewWlNjeDVjgVkCwjCCAr4wggGmoAMCAQICBHSG/cIwDQYJKoZIhvcNAQELBQAw" +
+        "LjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEw" +
+        "IBcNMTQwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG8xCzAJBgNVBAYTAlNF" +
+        "MRIwEAYDVQQKDAlZdWJpY28gQUIxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0" +
+        "ZXN0YXRpb24xKDAmBgNVBAMMH1l1YmljbyBVMkYgRUUgU2VyaWFsIDE5NTUwMDM4" +
+        "NDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASVXfOt9yR9MXXv/ZzE8xpOh466" +
+        "4YEJVmFQ+ziLLl9lJ79XQJqlgaUNCsUvGERcChNUihNTyKTlmnBOUjvATevto2ww" +
+        "ajAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4xLjQxNDgyLjEuMTATBgsrBgEEAYLl" +
+        "HAIBAQQEAwIFIDAhBgsrBgEEAYLlHAEBBAQSBBD4oBHzjApNFYAGFxEfntx9MAwG" +
+        "A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBADFcSIDmmlJ+OGaJvWn9Cqhv" +
+        "SeueToVFQVVvqtALOgCKHdwB+Wx29mg2GpHiMsgQp5xjB0ybbnpG6x212FxESJ+G" +
+        "inZD0ipchi7APwPlhIvjgH16zVX44a4e4hOsc6tLIOP71SaMsHuHgCcdH0vg5d2s" +
+        "c006WJe9TXO6fzV+ogjJnYpNKQLmCXoAXE3JBNwKGBIOCvfQDPyWmiiG5bGxYfPt" +
+        "y8Z3pnjX+1MDnM2hhr40ulMxlSNDnX/ZSnDyMGIbk8TOQmjTF02UO8auP8k3wt5D" +
+        "1rROIRU9+FCSX5WQYi68RuDrGMZB8P5+byoJqbKQdxn2LmE1oZAyohPAmLcoPO4=";
+    const testCtapPinAuthInvalidErrorBase64 = "Mw==";
+    if (window.internals) {
+        internals.setMockWebAuthenticationConfiguration({ hid: { supportClientPin: true, payloadBase64: [testCtapPinInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testCtapPinAuthInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testPinGetPinTokenResponseBase64, testCreationMessageBase64] } });
+        internals.withUserGesture(() => { input.focus(); });
+    }
+
+    const options = {
+        publicKey: {
+            rp: {
+                name: "localhost",
+            },
+            user: {
+                name: "John Appleseed",
+                id: new Uint8Array(16),
+                displayName: "Appleseed",
+            },
+            challenge: new Uint8Array(16),
+            pubKeyCredParams: [{ type: "public-key", alg: -7 }]
+        }
+    };
+
+    navigator.credentials.create(options).then(credential => {
+        // console.log("Succeeded!");
+        window.webkit.messageHandlers.testHandler.postMessage("Succeeded!");
+    }, error => {
+        // console.log(error.message);
+        window.webkit.messageHandlers.testHandler.postMessage(error.message);
+    });
+</script>

Copied: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html (from rev 256060, trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-error.html) (0 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-blocked-error.html	2020-02-07 22:16:54 UTC (rev 256062)
@@ -0,0 +1,34 @@
+<input type="text" id="input">
+<script>
+    const testCtapPinInvalidErrorBase64 = "MQ==";
+    const testPinGetRetriesResponseBase64 = "AKEDCA==";
+    const testPinGetKeyAgreementResponseBase64 = "AKEBpQECAzgYIAEhWCDodiWJbuTkbcAydm6Ah5YvNt+d/otWfzdjAVsZkKYOFCJYICfeYS1mQYvaGVBYHrxcjB2tcQyxTCL4yXBF9GEvsgyR";
+    const testCtapPinBlockedErrorBase64 = "Mg==";
+    if (window.internals) {
+        internals.setMockWebAuthenticationConfiguration({ hid: { supportClientPin: true, payloadBase64: [testCtapPinInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testCtapPinBlockedErrorBase64] } });
+        internals.withUserGesture(() => { input.focus(); });
+    }
+
+    const options = {
+        publicKey: {
+            rp: {
+                name: "localhost",
+            },
+            user: {
+                name: "John Appleseed",
+                id: new Uint8Array(16),
+                displayName: "Appleseed",
+            },
+            challenge: new Uint8Array(16),
+            pubKeyCredParams: [{ type: "public-key", alg: -7 }]
+        }
+    };
+
+    navigator.credentials.create(options).then(credential => {
+        // console.log("Succeeded!");
+        window.webkit.messageHandlers.testHandler.postMessage("Succeeded!");
+    }, error => {
+        // console.log(error.message);
+        window.webkit.messageHandlers.testHandler.postMessage(error.message);
+    });
+</script>

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html (0 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-get-pin-token-pin-invalid-error-retry.html	2020-02-07 22:16:54 UTC (rev 256062)
@@ -0,0 +1,56 @@
+<input type="text" id="input">
+<script>
+    const testCtapPinInvalidErrorBase64 = "MQ==";
+    const testPinGetRetriesResponseBase64 = "AKEDCA==";
+    const testPinGetKeyAgreementResponseBase64 = "AKEBpQECAzgYIAEhWCDodiWJbuTkbcAydm6Ah5YvNt+d/otWfzdjAVsZkKYOFCJYICfeYS1mQYvaGVBYHrxcjB2tcQyxTCL4yXBF9GEvsgyR";
+    const testPinGetPinTokenResponseBase64 = "AKECUBOk7rcOyRrqAB6TFvYeQfc=";
+    const testCreationMessageBase64 =
+        "AKMBZnBhY2tlZAJYxEbMf7lnnVWy25CS4cjZ5eHQK3WA8LSBLHcJYuHkj1rYQQAA" +
+        "AE74oBHzjApNFYAGFxEfntx9AEAoCK3O6P5OyXN6V/f+9nAga0NA2Cgp4V3mgSJ5" +
+        "jOHLMDrmxp/S0rbD+aihru1C0aAN3BkiM6GNy5nSlDVqOgTgpQECAyYgASFYIEFb" +
+        "he3RkNud6sgyraBGjlh1pzTlCZehQlL/b18HZ6WGIlggJgfUd/en9p5AIqMQbUni" +
+        "nEeXdFLkvW0/zV5BpEjjNxADo2NhbGcmY3NpZ1hHMEUCIQDKg+ZBmEBtf0lWq4Re" +
+        "dH4/i/LOYqOR4uR2NAj2zQmw9QIgbTXb4hvFbj4T27bv/rGrc+y+0puoYOBkBk9P" +
+        "mCewWlNjeDVjgVkCwjCCAr4wggGmoAMCAQICBHSG/cIwDQYJKoZIhvcNAQELBQAw" +
+        "LjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEw" +
+        "IBcNMTQwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG8xCzAJBgNVBAYTAlNF" +
+        "MRIwEAYDVQQKDAlZdWJpY28gQUIxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0" +
+        "ZXN0YXRpb24xKDAmBgNVBAMMH1l1YmljbyBVMkYgRUUgU2VyaWFsIDE5NTUwMDM4" +
+        "NDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASVXfOt9yR9MXXv/ZzE8xpOh466" +
+        "4YEJVmFQ+ziLLl9lJ79XQJqlgaUNCsUvGERcChNUihNTyKTlmnBOUjvATevto2ww" +
+        "ajAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4xLjQxNDgyLjEuMTATBgsrBgEEAYLl" +
+        "HAIBAQQEAwIFIDAhBgsrBgEEAYLlHAEBBAQSBBD4oBHzjApNFYAGFxEfntx9MAwG" +
+        "A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBADFcSIDmmlJ+OGaJvWn9Cqhv" +
+        "SeueToVFQVVvqtALOgCKHdwB+Wx29mg2GpHiMsgQp5xjB0ybbnpG6x212FxESJ+G" +
+        "inZD0ipchi7APwPlhIvjgH16zVX44a4e4hOsc6tLIOP71SaMsHuHgCcdH0vg5d2s" +
+        "c006WJe9TXO6fzV+ogjJnYpNKQLmCXoAXE3JBNwKGBIOCvfQDPyWmiiG5bGxYfPt" +
+        "y8Z3pnjX+1MDnM2hhr40ulMxlSNDnX/ZSnDyMGIbk8TOQmjTF02UO8auP8k3wt5D" +
+        "1rROIRU9+FCSX5WQYi68RuDrGMZB8P5+byoJqbKQdxn2LmE1oZAyohPAmLcoPO4=";
+    if (window.internals) {
+        internals.setMockWebAuthenticationConfiguration({ hid: { supportClientPin: true, payloadBase64: [testCtapPinInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testCtapPinInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testPinGetPinTokenResponseBase64, testCreationMessageBase64] } });
+        internals.withUserGesture(() => { input.focus(); });
+    }
+
+    const options = {
+        publicKey: {
+            rp: {
+                name: "localhost",
+            },
+            user: {
+                name: "John Appleseed",
+                id: new Uint8Array(16),
+                displayName: "Appleseed",
+            },
+            challenge: new Uint8Array(16),
+            pubKeyCredParams: [{ type: "public-key", alg: -7 }]
+        }
+    };
+
+    navigator.credentials.create(options).then(credential => {
+        // console.log("Succeeded!");
+        window.webkit.messageHandlers.testHandler.postMessage("Succeeded!");
+    }, error => {
+        // console.log(error.message);
+        window.webkit.messageHandlers.testHandler.postMessage(error.message);
+    });
+</script>

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-invalid-error-retry.html (0 => 256062)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-invalid-error-retry.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid-pin-invalid-error-retry.html	2020-02-07 22:16:54 UTC (rev 256062)
@@ -0,0 +1,56 @@
+<input type="text" id="input">
+<script>
+    const testCtapPinAuthInvalidErrorBase64 = "Mw==";
+    const testPinGetRetriesResponseBase64 = "AKEDCA==";
+    const testPinGetKeyAgreementResponseBase64 = "AKEBpQECAzgYIAEhWCDodiWJbuTkbcAydm6Ah5YvNt+d/otWfzdjAVsZkKYOFCJYICfeYS1mQYvaGVBYHrxcjB2tcQyxTCL4yXBF9GEvsgyR";
+    const testPinGetPinTokenResponseBase64 = "AKECUBOk7rcOyRrqAB6TFvYeQfc=";
+    const testCreationMessageBase64 =
+        "AKMBZnBhY2tlZAJYxEbMf7lnnVWy25CS4cjZ5eHQK3WA8LSBLHcJYuHkj1rYQQAA" +
+        "AE74oBHzjApNFYAGFxEfntx9AEAoCK3O6P5OyXN6V/f+9nAga0NA2Cgp4V3mgSJ5" +
+        "jOHLMDrmxp/S0rbD+aihru1C0aAN3BkiM6GNy5nSlDVqOgTgpQECAyYgASFYIEFb" +
+        "he3RkNud6sgyraBGjlh1pzTlCZehQlL/b18HZ6WGIlggJgfUd/en9p5AIqMQbUni" +
+        "nEeXdFLkvW0/zV5BpEjjNxADo2NhbGcmY3NpZ1hHMEUCIQDKg+ZBmEBtf0lWq4Re" +
+        "dH4/i/LOYqOR4uR2NAj2zQmw9QIgbTXb4hvFbj4T27bv/rGrc+y+0puoYOBkBk9P" +
+        "mCewWlNjeDVjgVkCwjCCAr4wggGmoAMCAQICBHSG/cIwDQYJKoZIhvcNAQELBQAw" +
+        "LjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEw" +
+        "IBcNMTQwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG8xCzAJBgNVBAYTAlNF" +
+        "MRIwEAYDVQQKDAlZdWJpY28gQUIxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0" +
+        "ZXN0YXRpb24xKDAmBgNVBAMMH1l1YmljbyBVMkYgRUUgU2VyaWFsIDE5NTUwMDM4" +
+        "NDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASVXfOt9yR9MXXv/ZzE8xpOh466" +
+        "4YEJVmFQ+ziLLl9lJ79XQJqlgaUNCsUvGERcChNUihNTyKTlmnBOUjvATevto2ww" +
+        "ajAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4xLjQxNDgyLjEuMTATBgsrBgEEAYLl" +
+        "HAIBAQQEAwIFIDAhBgsrBgEEAYLlHAEBBAQSBBD4oBHzjApNFYAGFxEfntx9MAwG" +
+        "A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBADFcSIDmmlJ+OGaJvWn9Cqhv" +
+        "SeueToVFQVVvqtALOgCKHdwB+Wx29mg2GpHiMsgQp5xjB0ybbnpG6x212FxESJ+G" +
+        "inZD0ipchi7APwPlhIvjgH16zVX44a4e4hOsc6tLIOP71SaMsHuHgCcdH0vg5d2s" +
+        "c006WJe9TXO6fzV+ogjJnYpNKQLmCXoAXE3JBNwKGBIOCvfQDPyWmiiG5bGxYfPt" +
+        "y8Z3pnjX+1MDnM2hhr40ulMxlSNDnX/ZSnDyMGIbk8TOQmjTF02UO8auP8k3wt5D" +
+        "1rROIRU9+FCSX5WQYi68RuDrGMZB8P5+byoJqbKQdxn2LmE1oZAyohPAmLcoPO4=";
+    if (window.internals) {
+        internals.setMockWebAuthenticationConfiguration({ hid: { supportClientPin: true, payloadBase64: [testCtapPinAuthInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testPinGetPinTokenResponseBase64, testCtapPinAuthInvalidErrorBase64, testPinGetRetriesResponseBase64, testPinGetKeyAgreementResponseBase64, testPinGetPinTokenResponseBase64, testCreationMessageBase64] } });
+        internals.withUserGesture(() => { input.focus(); });
+    }
+
+    const options = {
+        publicKey: {
+            rp: {
+                name: "localhost",
+            },
+            user: {
+                name: "John Appleseed",
+                id: new Uint8Array(16),
+                displayName: "Appleseed",
+            },
+            challenge: new Uint8Array(16),
+            pubKeyCredParams: [{ type: "public-key", alg: -7 }]
+        }
+    };
+
+    navigator.credentials.create(options).then(credential => {
+        // console.log("Succeeded!");
+        window.webkit.messageHandlers.testHandler.postMessage("Succeeded!");
+    }, error => {
+        // console.log(error.message);
+        window.webkit.messageHandlers.testHandler.postMessage(error.message);
+    });
+</script>
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to