Skip to content

Commit

Permalink
Apply patch. rdar://122813058
Browse files Browse the repository at this point in the history
Identifier: 272448.565@safari-7618.1.15.11-branch
  • Loading branch information
Dan Robson committed Feb 15, 2024
1 parent a69612c commit aff4c6a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 8 deletions.
17 changes: 17 additions & 0 deletions Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ void AuthenticatorCoordinator::create(const Document& document, CredentialCreati
}

options.extensions = extensionInputs;
if (options.extensions && options.extensions->largeBlob) {
if (options.extensions->largeBlob->read || options.extensions->largeBlob->write) {
promise.reject(Exception { ExceptionCode::NotAllowedError, "Read and write may not be present in largeBlob for registration."_s });
return;
}
}

// Step 4, 18-22.
if (!m_client) {
Expand Down Expand Up @@ -236,6 +242,17 @@ void AuthenticatorCoordinator::discoverFromExternalSource(const Document& docume
options.extensions->appid = appid;
}

if (options.extensions && options.extensions->largeBlob) {
if (!options.extensions->largeBlob->support.isEmpty()) {
promise.reject(Exception { ExceptionCode::NotAllowedError, "Support should not be present in largeBlob for assertion."_s });
return;
}
if (options.extensions->largeBlob->read && options.extensions->largeBlob->write) {
promise.reject(Exception { ExceptionCode::NotAllowedError, "Both read and write may not be present together in largeBlob."_s });
return;
}
}

// Step 4, 14-19.
if (!m_client) {
promise.reject(Exception { ExceptionCode::UnknownError, "Unknown internal error."_s });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ SOFT_LINK_CLASS_FOR_HEADER(WebKit, ASAuthorizationPublicKeyCredentialParameters)
SOFT_LINK_CLASS_FOR_HEADER(WebKit, ASAuthorizationPlatformPublicKeyCredentialDescriptor);
SOFT_LINK_CLASS_FOR_HEADER(WebKit, ASAuthorizationSecurityKeyPublicKeyCredentialDescriptor);
SOFT_LINK_CLASS_FOR_HEADER(WebKit, ASAuthorizationSecurityKeyPublicKeyCredentialAssertion);
SOFT_LINK_CLASS_FOR_HEADER(WebKit, ASAuthorizationPublicKeyCredentialLargeBlobAssertionInput);
SOFT_LINK_CLASS_FOR_HEADER(WebKit, ASAuthorizationPublicKeyCredentialLargeBlobRegistrationInput);
SOFT_LINK_CONSTANT_FOR_HEADER(WebKit, AuthenticationServices, ASAuthorizationErrorDomain, NSErrorDomain);
#define ASAuthorizationErrorDomain WebKit::get_AuthenticationServices_ASAuthorizationErrorDomain()
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@
SOFT_LINK_CLASS_FOR_SOURCE(WebKit, AuthenticationServices, ASAuthorizationPlatformPublicKeyCredentialDescriptor);
SOFT_LINK_CLASS_FOR_SOURCE(WebKit, AuthenticationServices, ASAuthorizationSecurityKeyPublicKeyCredentialDescriptor);
SOFT_LINK_CLASS_FOR_SOURCE(WebKit, AuthenticationServices, ASAuthorizationSecurityKeyPublicKeyCredentialAssertion);

SOFT_LINK_CLASS_FOR_SOURCE(WebKit, AuthenticationServices, ASAuthorizationPublicKeyCredentialLargeBlobAssertionInput);
SOFT_LINK_CLASS_FOR_SOURCE(WebKit, AuthenticationServices, ASAuthorizationPublicKeyCredentialLargeBlobRegistrationInput);
SOFT_LINK_CONSTANT_FOR_SOURCE(WebKit, AuthenticationServices, ASAuthorizationErrorDomain, NSErrorDomain);
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <wtf/Assertions.h>
#if HAVE(UNIFIED_ASC_AUTH_UI)

#import "config.h"
Expand Down Expand Up @@ -55,7 +56,7 @@
#import "AuthenticationServicesSoftLink.h"

@interface _WKASDelegate : NSObject {
WeakPtr<WebKit::WebPageProxy> m_page;
RetainPtr<WKWebView> m_view;
BlockPtr<void(ASAuthorization *, NSError *)> m_completionHandler;
}
- (instancetype)initWithPage:(WeakPtr<WebKit::WebPageProxy> &&)page completionHandler:(BlockPtr<void(ASAuthorization *, NSError *)> &&)completionHandler;
Expand All @@ -67,7 +68,8 @@ - (instancetype)initWithPage:(WeakPtr<WebKit::WebPageProxy> &&)page completionHa
if (!(self = [super init]))
return nil;

m_page = WTFMove(page);
if (page)
m_view = page->cocoaView();
m_completionHandler = WTFMove(completionHandler);

return self;
Expand All @@ -77,7 +79,9 @@ - (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthoriz
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [m_page->cocoaView() window];
if (m_view)
return [m_view window];
return nil;
#pragma clang diagnostic pop
}

Expand All @@ -103,6 +107,14 @@ - (void)authorizationController:(ASAuthorizationController *)controller didCompl

#if HAVE(WEB_AUTHN_AS_MODERN)

static inline ASAuthorizationPublicKeyCredentialLargeBlobSupportRequirement toASAuthorizationPublicKeyCredentialLargeBlobSupportRequirement(const String& requirement)
{
if (requirement == "required"_s)
return ASAuthorizationPublicKeyCredentialLargeBlobSupportRequirementRequired;
return ASAuthorizationPublicKeyCredentialLargeBlobSupportRequirementPreferred;
}


static inline RetainPtr<NSString> toASUserVerificationPreference(WebCore::UserVerificationRequirement requirement)
{
switch (requirement) {
Expand Down Expand Up @@ -203,6 +215,11 @@ - (void)authorizationController:(ASAuthorizationController *)controller didCompl
request.get().attestationPreference = toAttestationConveyancePreference(options.attestation).get();
if (options.authenticatorSelection)
request.get().userVerificationPreference = toASUserVerificationPreference(options.authenticatorSelection->userVerification).get();
if (options.extensions->largeBlob) {
// These are satisfied by validation in AuthenticatorCoordinator.
ASSERT(!options.extensions->largeBlob->read && !options.extensions->largeBlob->write);
request.get().largeBlob = adoptNS([allocASAuthorizationPublicKeyCredentialLargeBlobRegistrationInputInstance() initWithSupportRequirement:toASAuthorizationPublicKeyCredentialLargeBlobSupportRequirement(options.extensions->largeBlob->support)]).get();
}
[requests addObject:request.leakRef()];
}
if (includeSecurityKeyRequest) {
Expand Down Expand Up @@ -254,6 +271,15 @@ - (void)authorizationController:(ASAuthorizationController *)controller didCompl
RetainPtr request = adoptNS([[allocASAuthorizationPlatformPublicKeyCredentialProviderInstance() initWithRelyingPartyIdentifier:options.rpId] createCredentialAssertionRequestWithClientData:clientData.get()]);
if (platformAllowedCredentials)
request.get().allowedCredentials = platformAllowedCredentials.get();
if (options.extensions->largeBlob) {
// These are satisfied by validation in AuthenticatorCoordinator.
ASSERT(!options.extensions->largeBlob->support);
ASSERT(!(options.extensions->largeBlob->read && options.extensions->largeBlob->write));
auto largeBlob = options.extensions->largeBlob;
request.get().largeBlob = adoptNS([allocASAuthorizationPublicKeyCredentialLargeBlobAssertionInputInstance() initWithOperation:(largeBlob->read && *largeBlob->read) ? ASAuthorizationPublicKeyCredentialLargeBlobAssertionOperationRead : ASAuthorizationPublicKeyCredentialLargeBlobAssertionOperationWrite]).get();
if (largeBlob->write)
request.get().largeBlob.dataToWrite = WebCore::toNSData(*largeBlob->write).get();
}
[requests addObject:request.leakRef()];
}

Expand Down Expand Up @@ -315,10 +341,8 @@ - (void)authorizationController:(ASAuthorizationController *)controller didCompl
}
m_controller = WTFMove(controller);
m_completionHandler = WTFMove(handler);
m_delegate = adoptNS([[_WKASDelegate alloc] initWithPage:WTFMove(requestData.page) completionHandler:makeBlockPtr([weakThis = WeakPtr { *this }, this](ASAuthorization *auth, NSError *error) mutable {
if (!weakThis)
return;
ensureOnMainRunLoop([weakThis = WTFMove(weakThis), this, auth = retainPtr(auth)]() {
m_delegate = adoptNS([[_WKASDelegate alloc] initWithPage:WTFMove(requestData.page) completionHandler:makeBlockPtr([weakThis = WeakPtr { *this }](ASAuthorization *auth, NSError *error) mutable {
ensureOnMainRunLoop([weakThis = WTFMove(weakThis), auth = retainPtr(auth), error = retainPtr(error)]() {
if (!weakThis)
return;
WebCore::AuthenticatorResponseData response = { };
Expand All @@ -331,13 +355,21 @@ - (void)authorizationController:(ASAuthorizationController *)controller didCompl
response.attestationObject = toArrayBuffer(credential.get().rawAttestationObject);
response.transports = { };
response.clientDataJSON = toArrayBuffer(credential.get().rawClientDataJSON);
if (credential.get().largeBlob)
response.extensionOutputs = { { std::nullopt, std::nullopt, { { credential.get().largeBlob.isSupported, nullptr, std::nullopt } } } };
} else if ([auth.get().credential isKindOfClass:getASAuthorizationPlatformPublicKeyCredentialAssertionClass()]) {
auto credential = retainPtr((ASAuthorizationPlatformPublicKeyCredentialAssertion *)auth.get().credential);
response.rawId = toArrayBuffer(credential.get().credentialID);
response.authenticatorData = toArrayBuffer(credential.get().rawAuthenticatorData);
response.signature = toArrayBuffer(credential.get().signature);
response.userHandle = toArrayBuffer(credential.get().userID);
response.clientDataJSON = toArrayBuffer(credential.get().rawClientDataJSON);
if (credential.get().largeBlob) {
RefPtr<ArrayBuffer> protector = nullptr;
if (credential.get().largeBlob.readData)
protector = toArrayBuffer(credential.get().largeBlob.readData);
response.extensionOutputs = { { std::nullopt, std::nullopt, { { std::nullopt, protector, credential.get().largeBlob.didWrite } } } };
}
} else if ([auth.get().credential isKindOfClass:getASAuthorizationSecurityKeyPublicKeyCredentialRegistrationClass()]) {
auto credential = retainPtr((ASAuthorizationSecurityKeyPublicKeyCredentialRegistration *)auth.get().credential);
response.isAuthenticatorAttestationResponse = true;
Expand Down

0 comments on commit aff4c6a

Please sign in to comment.