FIRAppDistributionAuthPersistence.m 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Copyright 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import <AppAuth/AppAuth.h>
  15. #import "FIRAppDistributionAuthPersistence+Private.h"
  16. NS_ASSUME_NONNULL_BEGIN
  17. @implementation FIRAppDistributionAuthPersistence
  18. + (BOOL)clearAuthState {
  19. NSMutableDictionary *keychainQuery = [self getKeyChainQuery];
  20. OSStatus status = SecItemDelete((CFDictionaryRef)keychainQuery);
  21. if (status != errSecSuccess && status != errSecItemNotFound) {
  22. NSLog(@"AUTH ERROR. Cant delete auth state in keychain");
  23. } else {
  24. NSLog(@"AUTH SUCCESS! deleted auth state in the keychain");
  25. }
  26. return errSecSuccess || status == errSecItemNotFound;
  27. }
  28. + (OIDAuthState*)retrieveAuthState {
  29. NSMutableDictionary *keychainQuery = [self getKeyChainQuery];
  30. [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
  31. [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
  32. CFDataRef passwordData = NULL;
  33. NSData *result = nil;
  34. OSStatus status = SecItemCopyMatching((CFDictionaryRef)keychainQuery,
  35. (CFTypeRef *)&passwordData);
  36. if (status == noErr && 0 < [(__bridge NSData *)passwordData length]) {
  37. result = [(__bridge NSData *)passwordData copy];
  38. } else {
  39. NSLog(@"AUTH ERROR - cannot lookup keystore config");
  40. }
  41. if (passwordData != NULL) {
  42. CFRelease(passwordData);
  43. }
  44. OIDAuthState *authState = nil;
  45. if(result) {
  46. authState = (OIDAuthState *)[NSKeyedUnarchiver unarchiveObjectWithData:result];
  47. }
  48. return authState;
  49. }
  50. + (BOOL)persistAuthState:(OIDAuthState *)authState {
  51. NSData *authorizationData = [NSKeyedArchiver archivedDataWithRootObject:authState];
  52. NSMutableDictionary *keychainQuery = [self getKeyChainQuery];
  53. OSStatus status = noErr;
  54. if([self retrieveAuthState]) {
  55. NSLog(@"Auth state already persisted. Updating auth state");
  56. status = SecItemUpdate((CFDictionaryRef)keychainQuery, (CFDictionaryRef)@{(id)kSecValueData: authorizationData});
  57. } else {
  58. [keychainQuery setObject:authorizationData forKey:(id)kSecValueData];
  59. status = SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
  60. }
  61. if (status != noErr) {
  62. NSLog(@"AUTH ERROR. Cant store auth state in keychain");
  63. } else {
  64. NSLog(@"AUTH SUCCESS! Added auth state to keychain");
  65. }
  66. return status == noErr;
  67. }
  68. + (NSMutableDictionary*)getKeyChainQuery {
  69. NSMutableDictionary *keychainQuery =
  70. [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassGenericPassword, (id)kSecClass,
  71. @"OAuth", (id)kSecAttrGeneric,
  72. @"OAuth", (id)kSecAttrAccount,
  73. @"fire-fad-auth", (id)kSecAttrService,
  74. nil];
  75. return keychainQuery;
  76. }
  77. @end
  78. NS_ASSUME_NONNULL_END