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 // ItemCopyMatching wraps the |SecItemCopyMatching| function. 55 virtual OSStatus ItemCopyMatching(CFDictionaryRef query, CFTypeRef* result); 56 // ItemDelete wraps the |SecItemDelete| function. 57 virtual OSStatus ItemDelete(CFDictionaryRef query); 58 // ItemDelete wraps the |SecItemUpdate| function. 59 virtual OSStatus ItemUpdate(CFDictionaryRef query, 60 CFDictionaryRef keychain_data); 61 62 #if !BUILDFLAG(IS_IOS) 63 // TaskCopyValueForEntitlement wraps the |SecTaskCopyValueForEntitlement| 64 // function. Not available on iOS. 65 virtual base::apple::ScopedCFTypeRef<CFTypeRef> TaskCopyValueForEntitlement( 66 SecTaskRef task, 67 CFStringRef entitlement, 68 CFErrorRef* error); 69 #endif // !BUILDFLAG(IS_IOS) 70 71 // LAContextCanEvaluatePolicy wraps LAContext's canEvaluatePolicy method. 72 virtual BOOL LAContextCanEvaluatePolicy(LAPolicy policy, NSError** error); 73 74 protected: 75 AppleKeychainV2(); 76 virtual ~AppleKeychainV2(); 77 78 protected: 79 friend class base::NoDestructor<AppleKeychainV2>; 80 friend class ScopedTouchIdTestEnvironment; 81 friend class ScopedFakeAppleKeychainV2; 82 83 // Set an override to the singleton instance returned by |GetInstance|. The 84 // caller keeps ownership of the injected keychain and must remove the 85 // override by calling |ClearInstanceOverride| before deleting it. 86 static void SetInstanceOverride(AppleKeychainV2* keychain); 87 static void ClearInstanceOverride(); 88 }; 89 90 } // namespace crypto 91 92 #endif // CRYPTO_APPLE_KEYCHAIN_V2_H_ 93