-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Valet 4.0] Remove .always accessibility specifier #197
[Valet 4.0] Remove .always accessibility specifier #197
Conversation
bf6808c
to
a9bc846
Compare
a9bc846
to
a72acd2
Compare
Sources/Valet/Internal/SecItem.swift
Outdated
@@ -105,7 +104,7 @@ internal final class SecItem { | |||
// We should always be able to access the shared access group prefix because the accessibility of the above keychain data is set to `always`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to update this comment
Sources/Valet/Internal/SecItem.swift
Outdated
@@ -90,11 +90,10 @@ internal final class SecItem { | |||
} | |||
|
|||
guard status == errSecSuccess, let queryResult = result as? [CFString : AnyHashable], let accessGroup = queryResult[kSecAttrAccessGroup] as? String else { | |||
ErrorHandler.assertionFailure("Could not find shared access group prefix.") | |||
// We should always be able to access the shared access group prefix because the accessibility of the above keychain data is set to `always`. | |||
// We may not be able to access the shared access group prefix because the accessibility of the above keychain data is set to `afterFirstUnlock`. | |||
// In other words, we should never hit this code. This code is here as a failsafe to prevent a crash in a scenario where the keychain is entirely hosed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't entirely true any more
@@ -125,6 +135,9 @@ public final class SecureEnclaveValet: NSObject { | |||
/// - returns: The data currently stored in the keychain for the provided key. Returns `.itemNotFound` if no object exists in the keychain for the specified key, or if the keychain is inaccessible. Returns `.userCancelled` if the user cancels the user-presence prompt. | |||
public func object(forKey key: String, withPrompt userPrompt: String) -> SecureEnclave.Result<Data> { | |||
return execute(in: lock) { | |||
guard let keychainQuery = keychainQuery else { | |||
return .itemNotFound |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add a new result case for .keychainNotAccessible
? (applies throughout diff)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per the comment above:
Returns
.itemNotFound
if no object exists in the keychain for the specified key, or if the keychain is inaccessible.
So we're doing the right thing per the comment. Adding a new case here would be a breaking change. The Valet 4.0 code will throw
the right error (couldNotAccessKeychain
) in this case assuming #198 lands
@@ -135,6 +148,9 @@ public final class SecureEnclaveValet: NSObject { | |||
@objc(containsObjectForKey:) | |||
public func containsObject(forKey key: String) -> Bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should note in the header doc that it will return false if the keychain isn't accessible.
@@ -138,6 +151,9 @@ public final class SinglePromptSecureEnclaveValet: NSObject { | |||
@objc(containsObjectForKey:) | |||
public func containsObject(forKey key: String) -> Bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth noting in the header doc that it will return false
if the keychain is not accessible.
@@ -176,6 +198,9 @@ public final class SinglePromptSecureEnclaveValet: NSObject { | |||
@objc(allKeysWithUserPrompt:) | |||
public func allKeys(userPrompt: String) -> Set<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth noting the that an empty set will be returned when the keychain is not accessible.
@@ -168,6 +179,9 @@ public final class Valet: NSObject, KeychainQueryConvertible { | |||
@objc(containsObjectForKey:) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth noting in the header doc that it returns false
when keychain is not accessible.
@@ -196,6 +216,9 @@ public final class Valet: NSObject, KeychainQueryConvertible { | |||
@objc | |||
public func allKeys() -> Set<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing about header doc
Looks good overall, most comments are about documenting behavior. One thing to consider here is how consumers that were previously using |
This is a good point. I've added helper methods in ce5c0e5. |
Merging so I can deal with conflicts. Happy to take post-merge feedback on commits made after review. |
@@ -0,0 +1,738 @@ | |||
// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you accidentally duplicate this file? Not sure how this compiled since there's now 2 ValetIntegrationTests
classes...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed 🤦♂️. I’ve since removed the duplicate from the develop branch.
This PR removes the
.always
and.alwaysThisDeviceOnly
accessibility specifiers. These specifiers were deprecated in iOS 12, tvOS 12, macOS 10.14, and watchOS 5. They were deprecated because they do not provide any security protection for the user.The downside of removing these specifiers is that we were using
.alwaysThisDeviceOnly
to reliably determine the Bundle Seed ID (aka. App ID or Team ID). In this PR, I've removed the code that would returnINVALID_SHARED_ACCESS_GROUP_PREFIX
when determining the Bundle Seed ID. Instead, we returnnil
, which makes thekeychainQuery
nullable. If we can't determine the Bundle Seed ID, this means we can't access the keychain. This propagates to Valet (and friend) instances as a failure to access the keychain, since these objects need to unwrap theirkeychainQuery
before interacting with the keychain. If we don't yet have akeychainQuery
, we attempt to determine one before interacting with the keychain.Note that as part of this PR I removed the
KeychainQueryConvertible
protocol, since that protocol relied on a non-nullkeychainQuery
. It also wasn't providing us much value, as we only supported migrating values from aValet
(not aSecureEnclaveValet
orSinglePromptSecureEnclaveValet
).