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_USER_VERIFYING_KEY_H_ 6 #define CRYPTO_USER_VERIFYING_KEY_H_ 7 8 #include <memory> 9 #include <optional> 10 #include <string> 11 #include <variant> 12 #include <vector> 13 14 #include "base/containers/span.h" 15 #include "base/functional/callback.h" 16 #include "base/memory/ref_counted.h" 17 #include "build/build_config.h" 18 #include "crypto/crypto_export.h" 19 #include "crypto/scoped_lacontext.h" 20 #include "crypto/signature_verifier.h" 21 #include "crypto/unexportable_key.h" 22 23 namespace crypto { 24 25 typedef std::string UserVerifyingKeyLabel; 26 27 // UserVerifyingSigningKey is a hardware-backed key that triggers a user 28 // verification by the platform before a signature will be provided. 29 // 30 // Notes: 31 // - This is currently only supported on Windows and Mac. 32 // - This does not export a wrapped key because the Windows implementation uses 33 // the WinRT KeyCredentialManager which addresses stored keys by name. 34 // - The interface for this class will likely need to be generalized as support 35 // for other platforms is added. 36 class CRYPTO_EXPORT UserVerifyingSigningKey { 37 public: 38 virtual ~UserVerifyingSigningKey(); 39 40 // Sign invokes |callback| to provide a signature of |data|, or |nullopt| if 41 // an error occurs during signing. 42 virtual void Sign( 43 base::span<const uint8_t> data, 44 base::OnceCallback<void(std::optional<std::vector<uint8_t>>)> 45 callback) = 0; 46 47 // Provides the SPKI public key. 48 virtual std::vector<uint8_t> GetPublicKey() const = 0; 49 50 // Get a reference to the label used to create or retrieve this key. 51 virtual const UserVerifyingKeyLabel& GetKeyLabel() const = 0; 52 }; 53 54 // Reference-counted wrapper for UserVeriyingSigningKey. 55 class CRYPTO_EXPORT RefCountedUserVerifyingSigningKey 56 : public base::RefCountedThreadSafe<RefCountedUserVerifyingSigningKey> { 57 public: 58 explicit RefCountedUserVerifyingSigningKey( 59 std::unique_ptr<crypto::UserVerifyingSigningKey> key); 60 61 RefCountedUserVerifyingSigningKey(const RefCountedUserVerifyingSigningKey&) = 62 delete; 63 RefCountedUserVerifyingSigningKey& operator=( 64 const RefCountedUserVerifyingSigningKey&) = delete; 65 key()66 crypto::UserVerifyingSigningKey& key() const { return *key_; } 67 68 private: 69 friend class base::RefCountedThreadSafe<RefCountedUserVerifyingSigningKey>; 70 ~RefCountedUserVerifyingSigningKey(); 71 72 const std::unique_ptr<crypto::UserVerifyingSigningKey> key_; 73 }; 74 75 // UserVerifyingKeyProvider creates |UserVerifyingSigningKey|s. 76 class CRYPTO_EXPORT UserVerifyingKeyProvider { 77 public: 78 struct CRYPTO_EXPORT Config { 79 Config(); 80 Config(const Config& config) = delete; 81 Config& operator=(const Config& config) = delete; 82 Config(Config&& config); 83 Config& operator=(Config&& config); 84 ~Config(); 85 86 #if BUILDFLAG(IS_MAC) 87 // The keychain access group the key is shared with. The binary must be 88 // codesigned with the corresponding entitlement. 89 // https://developer.apple.com/documentation/bundleresources/entitlements/keychain-access-groups?language=objc 90 // This must be set to a non empty value when using user verifying keys on 91 // macOS. 92 std::string keychain_access_group; 93 94 // Optional LAContext to be used when retrieving and storing keys. Passing 95 // an authenticated LAContext lets you call UserVerifyingSigningKey::Sign() 96 // without triggering a macOS local authentication prompt. 97 std::optional<ScopedLAContext> lacontext; 98 #endif // BUILDFLAG(IS_MAC) 99 }; 100 101 virtual ~UserVerifyingKeyProvider(); 102 103 // Similar to |GenerateSigningKeySlowly| but the resulting signing key can 104 // only be used with a local user authentication by the platform. This can be 105 // called from any thread as the work is done asynchronously on a 106 // high-priority thread when the underlying platform is slow. 107 // Invokes |callback| with the resulting key, or nullptr on error. 108 virtual void GenerateUserVerifyingSigningKey( 109 base::span<const SignatureVerifier::SignatureAlgorithm> 110 acceptable_algorithms, 111 base::OnceCallback<void(std::unique_ptr<UserVerifyingSigningKey>)> 112 callback) = 0; 113 114 // Similar to |FromWrappedSigningKey| but uses a wrapped key that was 115 // generated from |GenerateUserVerifyingSigningKey|. This can be called from 116 // any thread as the work is done asynchronously on a high-priority thread 117 // when the underlying platform is slow. 118 // Invokes |callback| with the resulting key, or nullptr on error. 119 virtual void GetUserVerifyingSigningKey( 120 UserVerifyingKeyLabel key_label, 121 base::OnceCallback<void(std::unique_ptr<UserVerifyingSigningKey>)> 122 callback) = 0; 123 124 // Deletes a user verifying signing key. Work is be done asynchronously on a 125 // low-priority thread when the underlying platform is slow. 126 // Invokes |callback| with `true` if the key was found and deleted, `false` 127 // otherwise. 128 virtual void DeleteUserVerifyingKey( 129 UserVerifyingKeyLabel key_label, 130 base::OnceCallback<void(bool)> callback) = 0; 131 }; 132 133 // GetUserVerifyingKeyProvider returns |UserVerifyingKeyProvider| for the 134 // current platform, or nullptr if this is not implemented on the current 135 // platform. 136 // Note that this will return non null if keys are supported but not available, 137 // i.e. if |AreUserVerifyingKeysSupported| returns false. In that case, 138 // operations would fail. 139 CRYPTO_EXPORT std::unique_ptr<UserVerifyingKeyProvider> 140 GetUserVerifyingKeyProvider(UserVerifyingKeyProvider::Config config); 141 142 // Invokes the callback with true if UV keys can be used on the current 143 // platform, and false otherwise. `callback` can be invoked synchronously or 144 // asynchronously. 145 CRYPTO_EXPORT void AreUserVerifyingKeysSupported( 146 UserVerifyingKeyProvider::Config config, 147 base::OnceCallback<void(bool)> callback); 148 149 namespace internal { 150 151 CRYPTO_EXPORT void SetUserVerifyingKeyProviderForTesting( 152 std::unique_ptr<UserVerifyingKeyProvider> (*func)()); 153 154 } // namespace internal 155 156 } // namespace crypto 157 158 #endif // CRYPTO_USER_VERIFYING_KEY_H_ 159