NCKeyChainController.m 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /**
  2. * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
  3. * SPDX-License-Identifier: GPL-3.0-or-later
  4. */
  5. #import "NCKeyChainController.h"
  6. #import <CommonCrypto/CommonDigest.h>
  7. #import "NCAppBranding.h"
  8. #import "NextcloudTalk-Swift.h"
  9. @implementation NCKeyChainController
  10. NSString * const kNCTokenKey = @"ncToken";
  11. NSString * const kNCNormalPushTokenKey = @"ncNormalPushToken";
  12. NSString * const kNCPushKitTokenKey = @"ncPushKitToken";
  13. NSString * const kNCPNPublicKey = @"ncPNPublicKey";
  14. NSString * const kNCPNPrivateKey = @"ncPNPrivateKey";
  15. + (NCKeyChainController *)sharedInstance
  16. {
  17. static dispatch_once_t once;
  18. static NCKeyChainController *sharedInstance;
  19. dispatch_once(&once, ^{
  20. sharedInstance = [[self alloc] init];
  21. });
  22. return sharedInstance;
  23. }
  24. - (id)init
  25. {
  26. self = [super init];
  27. if (self) {
  28. _keychain = [UICKeyChainStore keyChainStoreWithService:bundleIdentifier accessGroup:groupIdentifier];
  29. }
  30. return self;
  31. }
  32. - (void)setToken:(NSString *)token forAccountId:(NSString *)accountId
  33. {
  34. [_keychain setString:token forKey:[NSString stringWithFormat:@"%@-%@", kNCTokenKey, accountId]];
  35. }
  36. - (NSString *)tokenForAccountId:(NSString *)accountId
  37. {
  38. return [_keychain stringForKey:[NSString stringWithFormat:@"%@-%@", kNCTokenKey, accountId]];
  39. }
  40. - (void)setPushNotificationPublicKey:(NSData *)privateKey forAccountId:(NSString *)accountId
  41. {
  42. [_keychain setData:privateKey forKey:[NSString stringWithFormat:@"%@-%@", kNCPNPublicKey, accountId]];
  43. }
  44. - (NSData *)pushNotificationPublicKeyForAccountId:(NSString *)accountId
  45. {
  46. return [_keychain dataForKey:[NSString stringWithFormat:@"%@-%@", kNCPNPublicKey, accountId]];
  47. }
  48. - (void)setPushNotificationPrivateKey:(NSData *)privateKey forAccountId:(NSString *)accountId
  49. {
  50. [_keychain setData:privateKey forKey:[NSString stringWithFormat:@"%@-%@", kNCPNPrivateKey, accountId]];
  51. }
  52. - (NSData *)pushNotificationPrivateKeyForAccountId:(NSString *)accountId
  53. {
  54. return [_keychain dataForKey:[NSString stringWithFormat:@"%@-%@", kNCPNPrivateKey, accountId]];
  55. }
  56. - (NSString *)pushTokenSHA512
  57. {
  58. NSString *token = [self combinedPushToken];
  59. if (!token) {
  60. return nil;
  61. }
  62. return [self createSHA512:token];
  63. }
  64. - (void)logCombinedPushToken
  65. {
  66. NSString *normalPushToken = [_keychain stringForKey:kNCNormalPushTokenKey];
  67. NSString *pushKitToken = [_keychain stringForKey:kNCPushKitTokenKey];
  68. if (normalPushToken && [normalPushToken length] >= 10) {
  69. [NCUtils log:[NSString stringWithFormat:@"Push notification, normal push token: %@... length %ld", [normalPushToken substringToIndex:10], [normalPushToken length]]];
  70. } else {
  71. [NCUtils log:@"Push notification, normal push token length < 10"];
  72. }
  73. if (pushKitToken && [pushKitToken length] >= 10) {
  74. [NCUtils log:[NSString stringWithFormat:@"Push notification, pushKit token: %@... length %ld", [pushKitToken substringToIndex:10], [pushKitToken length]]];
  75. } else {
  76. [NCUtils log:@"Push notification, pushKit token length < 10"];
  77. }
  78. }
  79. - (NSString *)combinedPushToken
  80. {
  81. NSString *normalPushToken = [_keychain stringForKey:kNCNormalPushTokenKey];
  82. NSString *pushKitToken = [_keychain stringForKey:kNCPushKitTokenKey];
  83. if (!normalPushToken || !pushKitToken) {
  84. return nil;
  85. }
  86. if ([NCUtils isiOSAppOnMac]) {
  87. // As CallKit is not supported on MacOS, we only supply the
  88. // normal push token, to generate local notifications for calls
  89. return normalPushToken;
  90. }
  91. return [NSString stringWithFormat:@"%@ %@", normalPushToken, pushKitToken];
  92. }
  93. - (void)removeAllItems
  94. {
  95. [UICKeyChainStore removeAllItemsForService:bundleIdentifier accessGroup:groupIdentifier];
  96. }
  97. #pragma mark - Utils
  98. - (NSString *)createSHA512:(NSString *)string
  99. {
  100. const char *cstr = [string cStringUsingEncoding:NSUTF8StringEncoding];
  101. NSData *data = [NSData dataWithBytes:cstr length:string.length];
  102. uint8_t digest[CC_SHA512_DIGEST_LENGTH];
  103. CC_SHA512(data.bytes, (unsigned int)data.length, digest);
  104. NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
  105. for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
  106. [output appendFormat:@"%02x", digest[i]];
  107. return output;
  108. }
  109. @end