xref: /aosp_15_r20/external/cronet/crypto/user_verifying_key.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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