Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / chromeos / platform_keys / platform_keys_service.h
blob23d44d35c8a5440668dff76b7bda7a46755b4111
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_PLATFORM_KEYS_SERVICE_H_
6 #define CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_PLATFORM_KEYS_SERVICE_H_
8 #include <queue>
9 #include <string>
10 #include <vector>
12 #include "base/callback_forward.h"
13 #include "base/macros.h"
14 #include "base/memory/linked_ptr.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "chrome/browser/chromeos/platform_keys/platform_keys.h"
18 #include "components/keyed_service/core/keyed_service.h"
20 namespace content {
21 class BrowserContext;
22 class WebContents;
25 namespace base {
26 class ListValue;
27 class Value;
30 namespace extensions {
31 class StateStore;
34 namespace net {
35 class X509Certificate;
36 typedef std::vector<scoped_refptr<X509Certificate>> CertificateList;
39 namespace chromeos {
41 class PlatformKeysService : public KeyedService {
42 public:
43 struct KeyEntry;
44 using KeyEntries = std::vector<KeyEntry>;
46 // The SelectDelegate is used to select a single certificate from all
47 // certificates matching a request (see SelectClientCertificates). E.g. this
48 // can happen by exposing UI to let the user select.
49 class SelectDelegate {
50 public:
51 using CertificateSelectedCallback = base::Callback<void(
52 const scoped_refptr<net::X509Certificate>& selection)>;
54 SelectDelegate();
55 virtual ~SelectDelegate();
57 // Called on an interactive SelectClientCertificates call with the list of
58 // matching certificates, |certs|.
59 // The certificate passed to |callback| will be forwarded to the
60 // calling extension and the extension will get unlimited sign permission
61 // for this cert. By passing null to |callback|, no cert will be selected.
62 // Must eventually call |callback| or be destructed. |callback| must not be
63 // called after this delegate is destructed.
64 // |web_contents| and |context| provide the context in which the
65 // certificates were requested and are not null.
66 virtual void Select(const std::string& extension_id,
67 const net::CertificateList& certs,
68 const CertificateSelectedCallback& callback,
69 content::WebContents* web_contents,
70 content::BrowserContext* context) = 0;
72 private:
73 DISALLOW_ASSIGN(SelectDelegate);
76 // Stores registration information in |state_store|, i.e. for each extension
77 // the list of public keys that are valid to be used for signing. Each key can
78 // be used for signing at most once.
79 // The format written to |state_store| is:
80 // kStateStorePlatformKeys maps to a list of strings.
81 // Each string is the base64 encoding of the DER representation of a public
82 // key's SPKI.
83 explicit PlatformKeysService(content::BrowserContext* browser_context,
84 extensions::StateStore* state_store);
85 ~PlatformKeysService() override;
87 // Sets the delegate which will be used for interactive
88 // SelectClientCertificates calls.
89 void SetSelectDelegate(scoped_ptr<SelectDelegate> delegate);
91 // Grants unlimited sign permission for |cert| to the extension with the ID
92 // |extension_id|.
93 void GrantUnlimitedSignPermission(const std::string& extension_id,
94 scoped_refptr<net::X509Certificate> cert);
96 // If the generation was successful, |public_key_spki_der| will contain the
97 // DER encoding of the SubjectPublicKeyInfo of the generated key and
98 // |error_message| will be empty. If it failed, |public_key_spki_der| will be
99 // empty and |error_message| contain an error message.
100 using GenerateKeyCallback =
101 base::Callback<void(const std::string& public_key_spki_der,
102 const std::string& error_message)>;
104 // Generates an RSA key pair with |modulus_length_bits| and registers the key
105 // to allow a single sign operation by the given extension. |token_id| is
106 // currently ignored, instead the user token associated with |browser_context|
107 // is always used. |callback| will be invoked with the resulting public key or
108 // an error.
109 // Will only call back during the lifetime of this object.
110 void GenerateRSAKey(const std::string& token_id,
111 unsigned int modulus_length_bits,
112 const std::string& extension_id,
113 const GenerateKeyCallback& callback);
115 // If signing was successful, |signature| will be contain the signature and
116 // |error_message| will be empty. If it failed, |signature| will be empty and
117 // |error_message| contain an error message.
118 using SignCallback = base::Callback<void(const std::string& signature,
119 const std::string& error_message)>;
121 // Digests |data|, applies PKCS1 padding and afterwards signs the data with
122 // the private key matching |params.public_key|. If a non empty token id is
123 // provided and the key is not found in that token, the operation aborts.
124 // If the extension does not have permissions for signing with this key, the
125 // operation aborts. In case of a one time permission (granted after
126 // generating the key), this function also removes the permission to prevent
127 // future signing attempts.
128 // |callback| will be invoked with the signature or an error message.
129 // Will only call back during the lifetime of this object.
130 void SignRSAPKCS1Digest(const std::string& token_id,
131 const std::string& data,
132 const std::string& public_key,
133 platform_keys::HashAlgorithm hash_algorithm,
134 const std::string& extension_id,
135 const SignCallback& callback);
137 // Applies PKCS1 padding and afterwards signs the data with the private key
138 // matching |params.public_key|. |data| is not digested. If a non empty token
139 // id is provided and the key is not found in that token, the operation
140 // aborts.
141 // The size of |data| (number of octets) must be smaller than k - 11, where k
142 // is the key size in octets.
143 // If the extension does not have permissions for signing with this key, the
144 // operation aborts. In case of a one time permission (granted after
145 // generating the key), this function also removes the permission to prevent
146 // future signing attempts.
147 // |callback| will be invoked with the signature or an error message.
148 // Will only call back during the lifetime of this object.
149 void SignRSAPKCS1Raw(const std::string& token_id,
150 const std::string& data,
151 const std::string& public_key,
152 const std::string& extension_id,
153 const SignCallback& callback);
155 // If the certificate request could be processed successfully, |matches| will
156 // contain the list of matching certificates (maybe empty) and |error_message|
157 // will be empty. If an error occurred, |matches| will be null and
158 // |error_message| contain an error message.
159 using SelectCertificatesCallback =
160 base::Callback<void(scoped_ptr<net::CertificateList> matches,
161 const std::string& error_message)>;
163 // Returns a list of certificates matching |request|.
164 // 1) all certificates that match the request (like being rooted in one of the
165 // give CAs) are determined. 2) if |interactive| is true, the currently set
166 // SelectDelegate is used to select a single certificate from these matches
167 // which will the extension will also be granted access to. 3) only
168 // certificates, that the extension has unlimited sign permission for, will be
169 // returned.
170 // |callback| will be invoked with these certificates or an error message.
171 // Will only call back during the lifetime of this object.
172 // |web_contents| must not be null.
173 void SelectClientCertificates(
174 const platform_keys::ClientCertificateRequest& request,
175 bool interactive,
176 const std::string& extension_id,
177 const SelectCertificatesCallback& callback,
178 content::WebContents* web_contents);
180 private:
181 using GetPlatformKeysCallback =
182 base::Callback<void(scoped_ptr<KeyEntries> platform_keys)>;
184 enum SignPermission { ONCE, UNLIMITED };
186 class PermissionUpdateTask;
187 class SelectTask;
188 class SignTask;
189 class Task;
191 // Starts |task| eventually. To ensure that at most one |Task| is running at a
192 // time, it queues |task| for later execution if necessary.
193 void StartOrQueueTask(scoped_ptr<Task> task);
195 // Must be called after |task| is done. |task| will be invalid after this
196 // call. This must not be called for any but the task that ran last. If any
197 // other tasks are queued (see StartOrQueueTask()), it will start the next
198 // one.
199 void TaskFinished(Task* task);
201 // Reads the list of public keys currently registered for |extension_id| from
202 // StateStore. Calls |callback| with the read list, or a new empty list if
203 // none existed. If an error occurred, calls |callback| with NULL.
204 void GetPlatformKeysOfExtension(const std::string& extension_id,
205 const GetPlatformKeysCallback& callback);
207 // Writes |platform_keys| to the state store of the extension with id
208 // |extension_id|.
209 void SetPlatformKeysOfExtension(const std::string& extension_id,
210 const KeyEntries& platform_keys);
212 // Callback used by |GenerateRSAKey|.
213 // If the key generation was successful, registers the generated public key
214 // for the given extension. If any error occurs during key generation or
215 // registration, calls |callback| with an error. Otherwise, on success, calls
216 // |callback| with the public key.
217 void GeneratedKey(const std::string& extension_id,
218 const GenerateKeyCallback& callback,
219 const std::string& public_key_spki_der,
220 const std::string& error_message);
222 // Callback used by |GeneratedKey|.
223 // |public_key_spki_der| will contain the X.509 Subject Public Key Info of
224 // the generated key in DER encoding. |task| points to the finished |Task|
225 // object.
226 void RegisteredGeneratedKey(const GenerateKeyCallback& callback,
227 const std::string& public_key_spki_der,
228 Task* task);
230 // Callback used by |GetPlatformKeysOfExtension|.
231 // Is called with |value| set to the PlatformKeys value read from the
232 // StateStore, which it forwards to |callback|. On error, calls |callback|
233 // with NULL; if no value existed, with an empty list.
234 void GotPlatformKeysOfExtension(const std::string& extension_id,
235 const GetPlatformKeysCallback& callback,
236 scoped_ptr<base::Value> value);
238 content::BrowserContext* browser_context_;
239 extensions::StateStore* state_store_;
240 scoped_ptr<SelectDelegate> select_delegate_;
241 std::queue<linked_ptr<Task>> tasks_;
242 base::WeakPtrFactory<PlatformKeysService> weak_factory_;
244 DISALLOW_COPY_AND_ASSIGN(PlatformKeysService);
247 } // namespace chromeos
249 #endif // CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_PLATFORM_KEYS_SERVICE_H_