FIRAppDistributionKeychainUtility.m 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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 "FIRAppDistributionKeychainUtility+Private.h"
  16. NSString *const kFIRAppDistributionKeychainErrorDomain = @"com.firebase.app_distribution.keychain";
  17. @implementation FIRAppDistributionKeychainUtility
  18. + (void)handleAuthStateError:(NSError **_Nullable)error
  19. description:(NSString *)description
  20. code:(int)code {
  21. if (error) {
  22. NSDictionary *userInfo = @{NSLocalizedDescriptionKey : description};
  23. *error = [NSError errorWithDomain:kFIRAppDistributionKeychainErrorDomain
  24. code:code
  25. userInfo:userInfo];
  26. }
  27. }
  28. + (BOOL)addKeychainItem:(nonnull NSMutableDictionary *)keychainQuery
  29. withDataDictionary:(nonnull NSData *)data {
  30. [keychainQuery setObject:data forKey:(id)kSecValueData];
  31. OSStatus status = SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
  32. return status == noErr ? YES : NO;
  33. }
  34. + (BOOL)updateKeychainItem:(nonnull NSMutableDictionary *)keychainQuery
  35. withDataDictionary:(nonnull NSData *)data {
  36. OSStatus status =
  37. SecItemUpdate((CFDictionaryRef)keychainQuery, (CFDictionaryRef) @{(id)kSecValueData : data});
  38. return status == noErr ? YES : NO;
  39. }
  40. + (BOOL)deleteKeychainItem:(nonnull NSMutableDictionary *)keychainQuery {
  41. OSStatus status = SecItemDelete((CFDictionaryRef)keychainQuery);
  42. return status != errSecSuccess && status != errSecItemNotFound ? NO : YES;
  43. }
  44. + (NSData *)fetchKeychainItemMatching:(nonnull NSMutableDictionary *)keychainQuery
  45. error:(NSError **_Nullable)error {
  46. NSData *keychainItem;
  47. OSStatus status = SecItemCopyMatching((CFDictionaryRef)keychainQuery, (void *)&keychainItem);
  48. if (status != noErr || 0 == [keychainItem length]) {
  49. if (error) {
  50. NSString *description =
  51. NSLocalizedString(@"Failed to fetch keychain item.",
  52. @"Error message for failure to retrieve auth state from keychain");
  53. [self handleAuthStateError:error description:description code:0];
  54. return nil;
  55. }
  56. }
  57. return keychainItem;
  58. }
  59. + (OIDAuthState *)unarchiveKeychainResult:(NSData *)result {
  60. return (OIDAuthState *)[NSKeyedUnarchiver unarchiveObjectWithData:result];
  61. }
  62. + (NSData *)archiveDataForKeychain:(OIDAuthState *)data {
  63. return [NSKeyedArchiver archivedDataWithRootObject:data];
  64. }
  65. @end