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