1 // Copyright 2024 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_V2_H_ 6 #define CRYPTO_APPLE_KEYCHAIN_V2_H_ 7 8 #import <CryptoTokenKit/CryptoTokenKit.h> 9 #import <Foundation/Foundation.h> 10 #import <LocalAuthentication/LocalAuthentication.h> 11 #import <Security/Security.h> 12 13 #include "crypto/crypto_export.h" 14 #include "base/apple/scoped_cftyperef.h" 15 #include "base/no_destructor.h" 16 17 namespace crypto { 18 19 // AppleKeychainV2 wraps iOS-style operations from the macOS Security framework 20 // to work with keys and keychain items. These functions are grouped here so 21 // they can be mocked out in testing. 22 class CRYPTO_EXPORT AppleKeychainV2 { 23 public: 24 static AppleKeychainV2& GetInstance(); 25 26 AppleKeychainV2(const AppleKeychainV2&) = delete; 27 AppleKeychainV2& operator=(const AppleKeychainV2&) = delete; 28 29 // Wraps the |TKTokenWatcher.tokenIDs| property. 30 virtual NSArray* GetTokenIDs(); 31 32 // KeyCreateRandomKey wraps the |SecKeyCreateRandomKey| function. 33 virtual base::apple::ScopedCFTypeRef<SecKeyRef> KeyCreateRandomKey( 34 CFDictionaryRef params, 35 CFErrorRef* error); 36 // KeyCreateSignature wraps the |SecKeyCreateSignature| function. 37 virtual base::apple::ScopedCFTypeRef<CFDataRef> KeyCreateSignature( 38 SecKeyRef key, 39 SecKeyAlgorithm algorithm, 40 CFDataRef data, 41 CFErrorRef* error); 42 // KeyCopyPublicKey wraps the |SecKeyCopyPublicKey| function. 43 virtual base::apple::ScopedCFTypeRef<SecKeyRef> KeyCopyPublicKey( 44 SecKeyRef key); 45 // KeyCopyExternalRepresentation wraps the |SecKeyCopyExternalRepresentation| 46 // function. 47 virtual base::apple::ScopedCFTypeRef<CFDataRef> KeyCopyExternalRepresentation( 48 SecKeyRef key, 49 CFErrorRef* error); 50 // KeyCopyAttributes wraps the |SecKeyCopyAttributes| function. 51 virtual base::apple::ScopedCFTypeRef<CFDictionaryRef> KeyCopyAttributes( 52 SecKeyRef key); 53 54 // ItemAdd wraps the |SecItemAdd| function. 55 virtual OSStatus ItemAdd(CFDictionaryRef attributes, CFTypeRef* result); 56 // ItemCopyMatching wraps the |SecItemCopyMatching| function. 57 virtual OSStatus ItemCopyMatching(CFDictionaryRef query, CFTypeRef* result); 58 // ItemDelete wraps the |SecItemDelete| function. 59 virtual OSStatus ItemDelete(CFDictionaryRef query); 60 // ItemDelete wraps the |SecItemUpdate| function. 61 virtual OSStatus ItemUpdate(CFDictionaryRef query, 62 CFDictionaryRef keychain_data); 63 64 #if !BUILDFLAG(IS_IOS) 65 // TaskCopyValueForEntitlement wraps the |SecTaskCopyValueForEntitlement| 66 // function. Not available on iOS. 67 virtual base::apple::ScopedCFTypeRef<CFTypeRef> TaskCopyValueForEntitlement( 68 SecTaskRef task, 69 CFStringRef entitlement, 70 CFErrorRef* error); 71 #endif // !BUILDFLAG(IS_IOS) 72 73 // LAContextCanEvaluatePolicy wraps LAContext's canEvaluatePolicy method. 74 virtual BOOL LAContextCanEvaluatePolicy(LAPolicy policy, NSError** error); 75 76 protected: 77 AppleKeychainV2(); 78 virtual ~AppleKeychainV2(); 79 80 protected: 81 friend class base::NoDestructor<AppleKeychainV2>; 82 friend class ScopedTouchIdTestEnvironment; 83 friend class ScopedFakeAppleKeychainV2; 84 85 // Set an override to the singleton instance returned by |GetInstance|. The 86 // caller keeps ownership of the injected keychain and must remove the 87 // override by calling |ClearInstanceOverride| before deleting it. 88 static void SetInstanceOverride(AppleKeychainV2* keychain); 89 static void ClearInstanceOverride(); 90 }; 91 92 } // namespace crypto 93 94 #endif // CRYPTO_APPLE_KEYCHAIN_V2_H_ 95