Skip to content

Commit

Permalink
[WebAuthn] Disable platform authenticator for disallowed rps
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=243844
<rdar://97789464>

Reviewed by Brent Fulgham.

In some circumstances it may be useful to quirk off the platform authenticator
for given rps. This patch hooks up some new internal SPI for that purpose.

* Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp:
(WebCore::AuthenticatorCoordinator::isUserVerifyingPlatformAuthenticatorAvailable const):
* Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.h:
* Source/WebCore/Modules/webauthn/AuthenticatorCoordinatorClient.h:
* Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp:
(WebCore::PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable):
* Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
* Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm:
* Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp:
(WebKit::WebAuthenticatorCoordinatorProxy::isUserVerifyingPlatformAuthenticatorAvailable):
* Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h:
* Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.messages.in:
* Source/WebKit/WebProcess/WebAuthentication/WebAuthenticatorCoordinator.cpp:
(WebKit::WebAuthenticatorCoordinator::isUserVerifyingPlatformAuthenticatorAvailable):
* Source/WebKit/WebProcess/WebAuthentication/WebAuthenticatorCoordinator.h:

Canonical link: https://commits.webkit.org/253497@main
  • Loading branch information
pascoej committed Aug 17, 2022
1 parent ee3946a commit 6bd8e23
Show file tree
Hide file tree
Showing 11 changed files with 15 additions and 13 deletions.
5 changes: 3 additions & 2 deletions Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp
Expand Up @@ -265,7 +265,7 @@ void AuthenticatorCoordinator::discoverFromExternalSource(const Document& docume
m_client->getAssertion(*frame, callerOrigin, clientDataJsonHash, options, requestOptions.mediation, scopeAndCrossOriginParent, WTFMove(callback));
}

void AuthenticatorCoordinator::isUserVerifyingPlatformAuthenticatorAvailable(DOMPromiseDeferred<IDLBoolean>&& promise) const
void AuthenticatorCoordinator::isUserVerifyingPlatformAuthenticatorAvailable(const Document& document, DOMPromiseDeferred<IDLBoolean>&& promise) const
{
// The following implements https://www.w3.org/TR/webauthn/#isUserVerifyingPlatformAuthenticatorAvailable
// as of 5 December 2017.
Expand All @@ -279,8 +279,9 @@ void AuthenticatorCoordinator::isUserVerifyingPlatformAuthenticatorAvailable(DOM
auto completionHandler = [promise = WTFMove(promise)] (bool result) mutable {
promise.resolve(result);
};

// Async operation are dispatched and handled in the messenger.
m_client->isUserVerifyingPlatformAuthenticatorAvailable(WTFMove(completionHandler));
m_client->isUserVerifyingPlatformAuthenticatorAvailable(document.securityOrigin(), WTFMove(completionHandler));
}


Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.h
Expand Up @@ -62,7 +62,7 @@ class AuthenticatorCoordinator final {
// The following methods implement static methods of PublicKeyCredential.
void create(const Document&, const PublicKeyCredentialCreationOptions&, WebAuthn::Scope, RefPtr<AbortSignal>&&, CredentialPromise&&) const;
void discoverFromExternalSource(const Document&, CredentialRequestOptions&&, const ScopeAndCrossOriginParent&, CredentialPromise&&) const;
void isUserVerifyingPlatformAuthenticatorAvailable(DOMPromiseDeferred<IDLBoolean>&&) const;
void isUserVerifyingPlatformAuthenticatorAvailable(const Document&, DOMPromiseDeferred<IDLBoolean>&&) const;
void isConditionalMediationAvailable(DOMPromiseDeferred<IDLBoolean>&&) const;

void resetUserGestureRequirement();
Expand Down
Expand Up @@ -63,7 +63,7 @@ class AuthenticatorCoordinatorClient : public CanMakeWeakPtr<AuthenticatorCoordi
virtual void makeCredential(const Frame&, const SecurityOrigin&, const Vector<uint8_t>&, const PublicKeyCredentialCreationOptions&, RequestCompletionHandler&&) = 0;
virtual void getAssertion(const Frame&, const SecurityOrigin&, const Vector<uint8_t>&, const PublicKeyCredentialRequestOptions&, MediationRequirement, const ScopeAndCrossOriginParent&, RequestCompletionHandler&&) = 0;
virtual void isConditionalMediationAvailable(QueryCompletionHandler&&) = 0;
virtual void isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&&) = 0;
virtual void isUserVerifyingPlatformAuthenticatorAvailable(const SecurityOrigin&, QueryCompletionHandler&&) = 0;

virtual void resetUserGestureRequirement() { }
};
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp
Expand Up @@ -67,7 +67,7 @@ PublicKeyCredential::PublicKeyCredential(Ref<AuthenticatorResponse>&& response)
void PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable(Document& document, DOMPromiseDeferred<IDLBoolean>&& promise)
{
if (auto* page = document.page())
page->authenticatorCoordinator().isUserVerifyingPlatformAuthenticatorAvailable(WTFMove(promise));
page->authenticatorCoordinator().isUserVerifyingPlatformAuthenticatorAvailable(document, WTFMove(promise));
}

} // namespace WebCore
Expand Down
Expand Up @@ -32,6 +32,7 @@
#else
@interface ASCWebKitSPISupport : NSObject
@property (class, nonatomic) BOOL shouldUseAlternateCredentialStore;
+ (BOOL)arePasskeysDisallowedForRelyingParty:(nonnull NSString *)relyingParty;
@end
#endif

Expand Down
Expand Up @@ -517,10 +517,10 @@ static inline void continueAfterRequest(RetainPtr<id <ASCCredentialProtocol>> cr
handler([getASCWebKitSPISupportClass() shouldUseAlternateCredentialStore]);
}

void WebAuthenticatorCoordinatorProxy::isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&& handler)
void WebAuthenticatorCoordinatorProxy::isUserVerifyingPlatformAuthenticatorAvailable(const SecurityOriginData& data, QueryCompletionHandler&& handler)
{
if ([getASCWebKitSPISupportClass() shouldUseAlternateCredentialStore]) {
handler(true);
handler(![getASCWebKitSPISupportClass() arePasskeysDisallowedForRelyingParty:data.securityOrigin()->domain()]);
return;
}

Expand Down
Expand Up @@ -114,7 +114,7 @@ void WebAuthenticatorCoordinatorProxy::handleRequest(WebAuthenticationRequestDat
}

#if !HAVE(UNIFIED_ASC_AUTH_UI)
void WebAuthenticatorCoordinatorProxy::isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&& handler)
void WebAuthenticatorCoordinatorProxy::isUserVerifyingPlatformAuthenticatorAvailable(const SecurityOriginData&, QueryCompletionHandler&& handler)
{
handler(LocalService::isAvailable());
}
Expand Down
Expand Up @@ -73,7 +73,7 @@ class WebAuthenticatorCoordinatorProxy : public IPC::MessageReceiver {
// Receivers.
void makeCredential(WebCore::FrameIdentifier, FrameInfoData&&, Vector<uint8_t>&& hash, WebCore::PublicKeyCredentialCreationOptions&&, bool processingUserGesture, RequestCompletionHandler&&);
void getAssertion(WebCore::FrameIdentifier, FrameInfoData&&, Vector<uint8_t>&& hash, WebCore::PublicKeyCredentialRequestOptions&&, WebCore::CredentialRequestOptions::MediationRequirement, std::optional<WebCore::SecurityOriginData>, bool processingUserGesture, RequestCompletionHandler&&);
void isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&&);
void isUserVerifyingPlatformAuthenticatorAvailable(const WebCore::SecurityOriginData&, QueryCompletionHandler&&);
void isConditionalMediationAvailable(QueryCompletionHandler&&);

void handleRequest(WebAuthenticationRequestData&&, RequestCompletionHandler&&);
Expand Down
Expand Up @@ -29,7 +29,7 @@ messages -> WebAuthenticatorCoordinatorProxy NotRefCounted {
MakeCredential(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, Vector<uint8_t> hash, struct WebCore::PublicKeyCredentialCreationOptions options, bool processingUserGesture) -> (struct WebCore::AuthenticatorResponseData data, enum:int WebCore::AuthenticatorAttachment attachment, struct WebCore::ExceptionData exception)
GetAssertion(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, Vector<uint8_t> hash, struct WebCore::PublicKeyCredentialRequestOptions options, enum:uint8_t WebCore::CredentialRequestOptions::MediationRequirement mediation, std::optional<WebCore::SecurityOriginData> parentOrigin, bool processingUserGesture) -> (struct WebCore::AuthenticatorResponseData data, enum:int WebCore::AuthenticatorAttachment attachment, struct WebCore::ExceptionData exception)
isConditionalMediationAvailable() -> (bool result)
IsUserVerifyingPlatformAuthenticatorAvailable() -> (bool result)
IsUserVerifyingPlatformAuthenticatorAvailable(struct WebCore::SecurityOriginData origin) -> (bool result)
}

#endif
Expand Up @@ -91,9 +91,9 @@ void WebAuthenticatorCoordinator::isConditionalMediationAvailable(QueryCompletio
m_webPage.sendWithAsyncReply(Messages::WebAuthenticatorCoordinatorProxy::isConditionalMediationAvailable(), WTFMove(handler));
};

void WebAuthenticatorCoordinator::isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&& handler)
void WebAuthenticatorCoordinator::isUserVerifyingPlatformAuthenticatorAvailable(const SecurityOrigin& origin, QueryCompletionHandler&& handler)
{
m_webPage.sendWithAsyncReply(Messages::WebAuthenticatorCoordinatorProxy::IsUserVerifyingPlatformAuthenticatorAvailable(), WTFMove(handler));
m_webPage.sendWithAsyncReply(Messages::WebAuthenticatorCoordinatorProxy::IsUserVerifyingPlatformAuthenticatorAvailable(origin.data()), WTFMove(handler));
}

bool WebAuthenticatorCoordinator::processingUserGesture(const Frame& frame, const FrameIdentifier& frameID)
Expand Down
Expand Up @@ -43,7 +43,7 @@ class WebAuthenticatorCoordinator final : public WebCore::AuthenticatorCoordinat
void makeCredential(const WebCore::Frame&, const WebCore::SecurityOrigin&, const Vector<uint8_t>&, const WebCore::PublicKeyCredentialCreationOptions&, WebCore::RequestCompletionHandler&&) final;
void getAssertion(const WebCore::Frame&, const WebCore::SecurityOrigin&, const Vector<uint8_t>& hash, const WebCore::PublicKeyCredentialRequestOptions&, WebCore::MediationRequirement, const std::pair<WebAuthn::Scope, std::optional<WebCore::SecurityOriginData>>&, WebCore::RequestCompletionHandler&&) final;
void isConditionalMediationAvailable(WebCore::QueryCompletionHandler&&) final;
void isUserVerifyingPlatformAuthenticatorAvailable(WebCore::QueryCompletionHandler&&) final;
void isUserVerifyingPlatformAuthenticatorAvailable(const WebCore::SecurityOrigin&, WebCore::QueryCompletionHandler&&) final;
void resetUserGestureRequirement() final { m_requireUserGesture = false; }

bool processingUserGesture(const WebCore::Frame&, const WebCore::FrameIdentifier&);
Expand Down

0 comments on commit 6bd8e23

Please sign in to comment.