Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm (274688 => 274689)
--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm 2021-03-18 23:42:55 UTC (rev 274688)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm 2021-03-18 23:46:23 UTC (rev 274689)
@@ -50,11 +50,8 @@
#if USE(APPLE_INTERNAL_SDK)
#import <WebKitAdditions/LocalAuthenticatorAdditions.h>
#else
-static bool shouldUseAlternateQuery() { return false; }
-static NSDictionary *alternateQueryForRPID(const String&)
+static void updateQueryIfNecessary(NSMutableDictionary *)
{
- ASSERT_NOT_REACHED();
- return nil;
}
#endif
@@ -129,7 +126,8 @@
static Optional<Vector<Ref<AuthenticatorAssertionResponse>>> getExistingCredentials(const String& rpId)
{
// Search Keychain for existing credential matched the RP ID.
- NSDictionary *query = @{
+ auto query = adoptNS([[NSMutableDictionary alloc] init]);
+ [query setDictionary:@{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
(id)kSecAttrLabel: rpId,
@@ -140,13 +138,11 @@
#else
(id)kSecAttrNoLegacy: @YES
#endif
- };
+ }];
+ updateQueryIfNecessary(query.get());
- if (shouldUseAlternateQuery())
- query = alternateQueryForRPID(rpId);
-
CFTypeRef attributesArrayRef = nullptr;
- OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &attributesArrayRef);
+ OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query.get(), &attributesArrayRef);
if (status && status != errSecItemNotFound)
return WTF::nullopt;
auto retainAttributesArray = adoptCF(attributesArrayRef);
@@ -188,7 +184,8 @@
void LocalAuthenticator::clearAllCredentials()
{
// FIXME<rdar://problem/57171201>: We should guard the method with a first party entitlement once WebAuthn is avaliable for third parties.
- NSDictionary* deleteQuery = @{
+ auto query = adoptNS([[NSMutableDictionary alloc] init]);
+ [query setDictionary:@{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrAccessGroup: (id)String(LocalAuthenticatiorAccessGroup),
#if HAVE(DATA_PROTECTION_KEYCHAIN)
@@ -196,8 +193,10 @@
#else
(id)kSecAttrNoLegacy: @YES
#endif
- };
- OSStatus status = SecItemDelete((__bridge CFDictionaryRef)deleteQuery);
+ }];
+ updateQueryIfNecessary(query.get());
+
+ OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query.get());
if (status && status != errSecItemNotFound)
LOG_ERROR(makeString("Couldn't clear all credential: "_s, status).utf8().data());
}
@@ -395,7 +394,8 @@
m_provisionalCredentialId = toNSData(credentialId);
#ifndef NDEBUG
- NSDictionary *credentialIdQuery = @{
+ auto query = adoptNS([[NSMutableDictionary alloc] init]);
+ [query setDictionary:@{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
(id)kSecAttrLabel: secAttrLabel,
@@ -405,8 +405,10 @@
#else
(id)kSecAttrNoLegacy: @YES
#endif
- };
- OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)credentialIdQuery, nullptr);
+ }];
+ updateQueryIfNecessary(query.get());
+
+ OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query.get(), nullptr);
ASSERT(!status);
#endif // NDEBUG
}
@@ -597,7 +599,8 @@
RetainPtr<CFDataRef> signature;
auto nsCredentialId = toNSData(response->rawId());
{
- NSDictionary *query = @{
+ auto query = adoptNS([[NSMutableDictionary alloc] init]);
+ [query setDictionary:@{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
(id)kSecAttrApplicationLabel: nsCredentialId.get(),
@@ -608,9 +611,11 @@
#else
(id)kSecAttrNoLegacy: @YES
#endif
- };
+ }];
+ updateQueryIfNecessary(query.get());
+
CFTypeRef privateKeyRef = nullptr;
- OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &privateKeyRef);
+ OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query.get(), &privateKeyRef);
if (status) {
receiveException({ UnknownError, makeString("Couldn't get the private key reference: ", status) });
return;
@@ -632,7 +637,8 @@
// Extra step: update the Keychain item with the same value to update its modification date such that LRU can be used
// for selectAssertionResponse
- NSDictionary *updateQuery = @{
+ auto query = adoptNS([[NSMutableDictionary alloc] init]);
+ [query setDictionary:@{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
(id)kSecAttrApplicationLabel: nsCredentialId.get(),
@@ -641,11 +647,13 @@
#else
(id)kSecAttrNoLegacy: @YES
#endif
- };
+ }];
+ updateQueryIfNecessary(query.get());
+
NSDictionary *updateParams = @{
(id)kSecAttrLabel: requestOptions.rpId,
};
- auto status = SecItemUpdate((__bridge CFDictionaryRef)updateQuery, (__bridge CFDictionaryRef)updateParams);
+ auto status = SecItemUpdate((__bridge CFDictionaryRef)query.get(), (__bridge CFDictionaryRef)updateParams);
if (status)
LOG_ERROR("Couldn't update the Keychain item: %d", status);
@@ -661,7 +669,8 @@
// Roll back the just created credential.
if (m_provisionalCredentialId) {
- NSDictionary* deleteQuery = @{
+ auto query = adoptNS([[NSMutableDictionary alloc] init]);
+ [query setDictionary:@{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrApplicationLabel: m_provisionalCredentialId.get(),
#if HAVE(DATA_PROTECTION_KEYCHAIN)
@@ -669,8 +678,10 @@
#else
(id)kSecAttrNoLegacy: @YES
#endif
- };
- OSStatus status = SecItemDelete((__bridge CFDictionaryRef)deleteQuery);
+ }];
+ updateQueryIfNecessary(query.get());
+
+ OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query.get());
if (status)
LOG_ERROR(makeString("Couldn't delete provisional credential while handling error: "_s, status).utf8().data());
}
@@ -695,7 +706,8 @@
if (memcmp(userHandle->data(), creationOptions.user.idVector.data(), userHandle->byteLength()))
return false;
- NSDictionary* deleteQuery = @{
+ auto query = adoptNS([[NSMutableDictionary alloc] init]);
+ [query setDictionary:@{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrApplicationLabel: toNSData(credential->rawId()).get(),
#if HAVE(DATA_PROTECTION_KEYCHAIN)
@@ -703,8 +715,10 @@
#else
(id)kSecAttrNoLegacy: @YES
#endif
- };
- OSStatus status = SecItemDelete((__bridge CFDictionaryRef)deleteQuery);
+ }];
+ updateQueryIfNecessary(query.get());
+
+ OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query.get());
if (status && status != errSecItemNotFound)
LOG_ERROR(makeString("Couldn't delete older credential: "_s, status).utf8().data());
return true;