Skip to content

Commit b149cc0

Browse files
Mueslyflovilmart
authored andcommitted
Migrates keychain accessibility to allow restoring session from iCloud backup (parse-community#1299)
1 parent 82a0e83 commit b149cc0

File tree

1 file changed

+38
-5
lines changed

1 file changed

+38
-5
lines changed

Parse/Parse/Internal/PFKeychainStore.m

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ + (NSDictionary *)_keychainQueryTemplateForService:(NSString *)service {
4141
#pragma clang diagnostic push
4242
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
4343
if (&kSecAttrAccessible != nil) {
44-
query[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
44+
query[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlock;
4545
}
4646
#pragma clang diagnostic pop
4747

@@ -104,10 +104,43 @@ - (NSData *)_dataForKey:(NSString *)key {
104104
//recover data
105105
CFDataRef data = NULL;
106106
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&data);
107-
if (status != errSecSuccess && status != errSecItemNotFound) {
108-
PFLogError(PFLoggingTagCommon,
109-
@"PFKeychainStore failed to get object for key '%@', with error: %ld", key, (long)status);
110-
}
107+
BOOL logError = NO;
108+
109+
if (status != errSecSuccess) {
110+
if(status == errSecItemNotFound) {
111+
// Try seeing if we have migrated from kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly to kSecAttrAccessibleAfterFirstUnlock
112+
query[(__bridge NSString *)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
113+
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&data);
114+
if(status == errSecSuccess) {
115+
// Migrate to new Accessible flag
116+
NSMutableDictionary *saveQuery = [self.keychainQueryTemplate mutableCopy];
117+
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:(__bridge NSData*)data];
118+
saveQuery[(__bridge NSString *)kSecAttrAccount] = key;
119+
saveQuery[(__bridge NSString *)kSecValueData] = archivedData;
120+
saveQuery[(__bridge NSString *)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
121+
NSDictionary *migrationData = @{ (__bridge NSString *)kSecAttrAccessible : (__bridge NSString *)kSecAttrAccessibleAfterFirstUnlock};
122+
123+
OSStatus migrationStatus = SecItemUpdate((__bridge CFDictionaryRef)saveQuery, (__bridge CFDictionaryRef)migrationData);
124+
125+
if (migrationStatus != errSecSuccess) {
126+
logError = YES;
127+
PFLogError(PFLoggingTagCommon,
128+
@"PFKeychainStore failed to set object for key '%@', with error: %ld", key, (long)migrationStatus);
129+
}
130+
}
131+
else {
132+
// Not found on either Accessible key, so assume new
133+
}
134+
}
135+
else {
136+
logError = YES;
137+
}
138+
139+
if(logError) {
140+
PFLogError(PFLoggingTagCommon,
141+
@"PFKeychainStore failed to get object for key '%@', with error: %ld", key, (long)status);
142+
}
143+
}
111144
return CFBridgingRelease(data);
112145
}
113146

0 commit comments

Comments
 (0)