1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CRYPTO_APPLE_KEYCHAIN_H_ 6 #define CRYPTO_APPLE_KEYCHAIN_H_ 7 8 #include <Security/Security.h> 9 10 #include <optional> 11 #include "build/build_config.h" 12 #include "crypto/crypto_export.h" 13 14 namespace crypto { 15 16 #if BUILDFLAG(IS_IOS) 17 using AppleSecKeychainItemRef = void*; 18 #else 19 using AppleSecKeychainItemRef = SecKeychainItemRef; 20 #endif 21 22 // Wraps the KeychainServices API in a very thin layer, to allow it to be 23 // mocked out for testing. 24 25 // See Keychain Services documentation for function documentation, as these call 26 // through directly to their Keychain Services equivalents (Foo -> 27 // SecKeychainFoo). The only exception is Free, which should be used for 28 // anything returned from this class that would normally be freed with 29 // CFRelease (to aid in testing). 30 class CRYPTO_EXPORT AppleKeychain { 31 public: 32 AppleKeychain(); 33 34 AppleKeychain(const AppleKeychain&) = delete; 35 AppleKeychain& operator=(const AppleKeychain&) = delete; 36 37 virtual ~AppleKeychain(); 38 39 virtual OSStatus FindGenericPassword(UInt32 service_name_length, 40 const char* service_name, 41 UInt32 account_name_length, 42 const char* account_name, 43 UInt32* password_length, 44 void** password_data, 45 AppleSecKeychainItemRef* item) const; 46 47 virtual OSStatus ItemFreeContent(void* data) const; 48 49 virtual OSStatus AddGenericPassword(UInt32 service_name_length, 50 const char* service_name, 51 UInt32 account_name_length, 52 const char* account_name, 53 UInt32 password_length, 54 const void* password_data, 55 AppleSecKeychainItemRef* item) const; 56 57 #if BUILDFLAG(IS_MAC) 58 virtual OSStatus ItemDelete(AppleSecKeychainItemRef item) const; 59 #endif // !BUILDFLAG(IS_MAC) 60 }; 61 62 #if BUILDFLAG(IS_MAC) 63 64 // Sets whether Keychain Services is permitted to display UI if needed by 65 // calling SecKeychainSetUserInteractionAllowed. This operates in a scoped 66 // fashion: on destruction, the previous state will be restored. This is useful 67 // to interact with the Keychain on a best-effort basis, without displaying any 68 // Keychain Services UI (which is beyond the application's control) to the user. 69 class CRYPTO_EXPORT ScopedKeychainUserInteractionAllowed { 70 public: 71 ScopedKeychainUserInteractionAllowed( 72 const ScopedKeychainUserInteractionAllowed&) = delete; 73 ScopedKeychainUserInteractionAllowed& operator=( 74 const ScopedKeychainUserInteractionAllowed&) = delete; 75 76 explicit ScopedKeychainUserInteractionAllowed(Boolean allowed, 77 OSStatus* status = nullptr); 78 79 ~ScopedKeychainUserInteractionAllowed(); 80 81 private: 82 std::optional<Boolean> was_allowed_; 83 }; 84 85 #endif // BUILDFLAG(IS_MAC) 86 87 } // namespace crypto 88 89 #endif // CRYPTO_APPLE_KEYCHAIN_H_ 90