apple_keychain_mac.cc 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "crypto/apple_keychain.h"
  5. #include "base/memory/raw_ptr.h"
  6. #include "base/synchronization/lock.h"
  7. #include "crypto/mac_security_services_lock.h"
  8. namespace {
  9. // Supports the pattern where a function F(T* out) allows |out| to be nullptr
  10. // but its implementation requires a T variable even in the absence of |out|.
  11. // Such a function can maintain a local OptionalOutParameter<T> to provide the
  12. // internal T value, assigning its value to *out on destruction if possible.
  13. template <typename T>
  14. class OptionalOutParameter {
  15. public:
  16. OptionalOutParameter(const OptionalOutParameter&) = delete;
  17. OptionalOutParameter& operator=(const OptionalOutParameter&) = delete;
  18. OptionalOutParameter(T* out, T value = T()) : out_(out), value_(value) {}
  19. ~OptionalOutParameter() {
  20. if (out_) {
  21. *out_ = value_;
  22. }
  23. }
  24. OptionalOutParameter& operator=(T value) {
  25. value_ = value;
  26. return *this;
  27. }
  28. operator T() const { return value_; }
  29. private:
  30. const raw_ptr<T> out_;
  31. T value_;
  32. };
  33. } // namespace
  34. // Much of the Keychain API was marked deprecated as of the macOS 13 SDK.
  35. // Removal of its use is tracked in https://crbug.com/1348251 but deprecation
  36. // warnings are disabled in the meanwhile.
  37. #pragma clang diagnostic push
  38. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  39. namespace crypto {
  40. AppleKeychain::AppleKeychain() = default;
  41. AppleKeychain::~AppleKeychain() = default;
  42. OSStatus AppleKeychain::FindGenericPassword(
  43. UInt32 service_name_length,
  44. const char* service_name,
  45. UInt32 account_name_length,
  46. const char* account_name,
  47. UInt32* password_length,
  48. void** password_data,
  49. AppleSecKeychainItemRef* item) const {
  50. base::AutoLock lock(GetMacSecurityServicesLock());
  51. return SecKeychainFindGenericPassword(
  52. nullptr, service_name_length, service_name, account_name_length,
  53. account_name, password_length, password_data, item);
  54. }
  55. OSStatus AppleKeychain::ItemFreeContent(void* data) const {
  56. base::AutoLock lock(GetMacSecurityServicesLock());
  57. return SecKeychainItemFreeContent(nullptr, data);
  58. }
  59. OSStatus AppleKeychain::AddGenericPassword(
  60. UInt32 service_name_length,
  61. const char* service_name,
  62. UInt32 account_name_length,
  63. const char* account_name,
  64. UInt32 password_length,
  65. const void* password_data,
  66. AppleSecKeychainItemRef* item) const {
  67. base::AutoLock lock(GetMacSecurityServicesLock());
  68. return SecKeychainAddGenericPassword(
  69. nullptr, service_name_length, service_name, account_name_length,
  70. account_name, password_length, password_data, item);
  71. }
  72. OSStatus AppleKeychain::ItemDelete(AppleSecKeychainItemRef item) const {
  73. base::AutoLock lock(GetMacSecurityServicesLock());
  74. return SecKeychainItemDelete(item);
  75. }
  76. ScopedKeychainUserInteractionAllowed::ScopedKeychainUserInteractionAllowed(
  77. Boolean allowed,
  78. OSStatus* status) {
  79. Boolean was_allowed;
  80. OptionalOutParameter<OSStatus> local_status(
  81. status, SecKeychainGetUserInteractionAllowed(&was_allowed));
  82. if (local_status != noErr) {
  83. return;
  84. }
  85. local_status = SecKeychainSetUserInteractionAllowed(allowed);
  86. if (local_status != noErr) {
  87. return;
  88. }
  89. was_allowed_ = was_allowed;
  90. }
  91. ScopedKeychainUserInteractionAllowed::~ScopedKeychainUserInteractionAllowed() {
  92. if (was_allowed_) {
  93. SecKeychainSetUserInteractionAllowed(*was_allowed_);
  94. }
  95. }
  96. #pragma clang diagnostic pop
  97. } // namespace crypto