-
Notifications
You must be signed in to change notification settings - Fork 219
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
Fix keychains that rely on kSecAttrAccessGroup on macOS Catalina #193
Conversation
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.
Is this going to affect accessing values set using older versions of Valet?
Use it unless you specifically need access to items previously stored in a legacy keychain in macOS.
Not sure what a "legacy" keychain is in this context. If it includes anything before this attribute was set, that might be problematic.
Good catch! I've added a commit that adds this field when setting a value, but doesn't require it when reading values out of the keychain. Note that I've run all macOS tests locally in a signed environment, and they are passing with this latest update. These tests include our tests that Legacy Valet instances can write values that current Valet instances can read. Given that those are passing, I think we're good to go. |
8e35ea5
to
e1baeba
Compare
2ccc52a
to
63c3397
Compare
Would love to get this fix into a release so that Mac apps can recover from this issue. Can I get another review? |
Based on testing, it appears that The trade-off here is that if we |
I've updated this PR to always use |
Upon further investigation, this isn't entirely true. We encode the accessibility in the Additionally, since That said, I still think protecting against a future where Apple enforces the presence of |
… migration of objects from other Valets
…prevent data loss on iOS, tvOS, and watchOS
kSecAttrAccessible : Accessibility.alwaysThisDeviceOnly.secAccessibilityAttribute, | ||
] | ||
|
||
if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) { |
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.
There's no harm in using kSecUseDataProtectionKeychain
when looking up the sharedAccessGroupPrefix
on all operating systems.
Sources/Valet/Internal/SecItem.swift
Outdated
|
||
if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) { | ||
// Update the account to be distinct, since we're changing the query. | ||
query[kSecAttrAccount] = "SharedAccessGroupAlwaysAccessiblePrefixPlaceholderWithDataProtection" |
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.
If we don't do this, a SharedAccessGroupAlwaysAccessiblePrefixPlaceholder
that was added without kSecUseDataProtectionKeychain
wouldn't be found on SecItemCopy
, but trying to add that account/data to the keychain would return a errSecDuplicateItem
.
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.
Nevermind. Looks like errSecDuplicateItem
is only returned when a kSecAttrService
or kSecAttrAccount
overlaps. Removing this line.
Sources/Valet/Internal/Service.swift
Outdated
|
||
|
||
#if os(macOS) | ||
if #available(macOS 10.15, *) { |
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.
I only add kSecUseDataProtectionKeychain
to our base query on macOS, since macOS is the only OS that needs this value.
Adding this value to the base query is a breaking change, since anything some items written to the keychain without kSecUseDataProtectionKeychain
set will not be read when kSecUseDataProtectionKeychain
is in the base query. I wrote migrateObjectsFromPreCatalina
to solve this issue on macOS, but decided to allow non-Mac customers to continue using the keychain without migrating objects to include kSecUseDataProtectionKeychain
.
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.
After sleeping on it: I realize we can use kSecUseDataProtectionKeychain
on all platforms. I had written a test to prove this.
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.
From Apple's documentation:
It’s highly recommended that you set the value of this key to true for all keychain operations. This key helps to improve the portability of your code across platforms. Use it unless you specifically need access to items previously stored in a legacy keychain in macOS.
Fixed in 0c9799c
@NickEntin this PR is now ready for review again. |
…atalina unless test environment is signed
…l only meaningfully update objects written from macOS
471507f
to
f4de2d4
Compare
f4de2d4
to
f60f87d
Compare
It looks like Catalina broke our logic for finding a
sharedAccessGroupPrefix
. There's new documentation for kSecAttrAccessGroup in macOS Catalina:This PR adds kSecUseDataProtectionKeychain to all keychain queries on
macOS
. This follows Apple's recommendation: