• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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