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_
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/key_permissions.h"
18 #include "chrome/browser/chromeos/platform_keys/platform_keys.h"
19 #include "components/keyed_service/core/keyed_service.h"
33 namespace extensions
{
38 class X509Certificate
;
39 typedef std::vector
<scoped_refptr
<X509Certificate
>> CertificateList
;
48 class PlatformKeysService
: public KeyedService
{
50 // The SelectDelegate is used to select a single certificate from all
51 // certificates matching a request (see SelectClientCertificates). E.g. this
52 // can happen by exposing UI to let the user select.
53 class SelectDelegate
{
55 using CertificateSelectedCallback
= base::Callback
<void(
56 const scoped_refptr
<net::X509Certificate
>& selection
)>;
59 virtual ~SelectDelegate();
61 // Called on an interactive SelectClientCertificates call with the list of
62 // matching certificates, |certs|.
63 // The certificate passed to |callback| will be forwarded to the
64 // calling extension and the extension will get unlimited sign permission
65 // for this cert. By passing null to |callback|, no cert will be selected.
66 // Must eventually call |callback| or be destructed. |callback| must not be
67 // called after this delegate is destructed.
68 // |web_contents| and |context| provide the context in which the
69 // certificates were requested and are not null.
70 virtual void Select(const std::string
& extension_id
,
71 const net::CertificateList
& certs
,
72 const CertificateSelectedCallback
& callback
,
73 content::WebContents
* web_contents
,
74 content::BrowserContext
* context
) = 0;
77 DISALLOW_ASSIGN(SelectDelegate
);
80 // Stores registration information in |state_store|, i.e. for each extension
81 // the list of public keys that are valid to be used for signing. See
82 // |KeyPermissions| for details.
83 // |browser_context| and |state_store| must not be null and outlive this
85 explicit PlatformKeysService(bool profile_is_managed
,
86 PrefService
* profile_prefs
,
87 policy::PolicyService
* profile_policies
,
88 content::BrowserContext
* browser_context
,
89 extensions::StateStore
* state_store
);
91 ~PlatformKeysService() override
;
93 // Sets the delegate which will be used for interactive
94 // SelectClientCertificates calls.
95 void SetSelectDelegate(scoped_ptr
<SelectDelegate
> delegate
);
97 // If the generation was successful, |public_key_spki_der| will contain the
98 // DER encoding of the SubjectPublicKeyInfo of the generated key and
99 // |error_message| will be empty. If it failed, |public_key_spki_der| will be
100 // empty and |error_message| contain an error message.
101 using GenerateKeyCallback
=
102 base::Callback
<void(const std::string
& public_key_spki_der
,
103 const std::string
& error_message
)>;
105 // Generates an RSA key pair with |modulus_length_bits| and registers the key
106 // to allow a single sign operation by the given extension. |token_id| is
107 // currently ignored, instead the user token associated with |browser_context|
108 // is always used. |callback| will be invoked with the resulting public key or
110 // Will only call back during the lifetime of this object.
111 void GenerateRSAKey(const std::string
& token_id
,
112 unsigned int modulus_length_bits
,
113 const std::string
& extension_id
,
114 const GenerateKeyCallback
& callback
);
116 // If signing was successful, |signature| will be contain the signature and
117 // |error_message| will be empty. If it failed, |signature| will be empty and
118 // |error_message| contain an error message.
119 using SignCallback
= base::Callback
<void(const std::string
& signature
,
120 const std::string
& error_message
)>;
122 // Digests |data|, applies PKCS1 padding and afterwards signs the data with
123 // the private key matching |params.public_key|. If a non empty token id is
124 // provided and the key is not found in that token, the operation aborts.
125 // If the extension does not have permissions for signing with this key, the
126 // operation aborts. In case of a one time permission (granted after
127 // generating the key), this function also removes the permission to prevent
128 // future signing attempts.
129 // |callback| will be invoked with the signature or an error message.
130 // Will only call back during the lifetime of this object.
131 void SignRSAPKCS1Digest(const std::string
& token_id
,
132 const std::string
& data
,
133 const std::string
& public_key
,
134 platform_keys::HashAlgorithm hash_algorithm
,
135 const std::string
& extension_id
,
136 const SignCallback
& callback
);
138 // Applies PKCS1 padding and afterwards signs the data with the private key
139 // matching |params.public_key|. |data| is not digested. If a non empty token
140 // id is provided and the key is not found in that token, the operation
142 // The size of |data| (number of octets) must be smaller than k - 11, where k
143 // is the key size in octets.
144 // If the extension does not have permissions for signing with this key, the
145 // operation aborts. In case of a one time permission (granted after
146 // generating the key), this function also removes the permission to prevent
147 // future signing attempts.
148 // |callback| will be invoked with the signature or an error message.
149 // Will only call back during the lifetime of this object.
150 void SignRSAPKCS1Raw(const std::string
& token_id
,
151 const std::string
& data
,
152 const std::string
& public_key
,
153 const std::string
& extension_id
,
154 const SignCallback
& callback
);
156 // If the certificate request could be processed successfully, |matches| will
157 // contain the list of matching certificates (maybe empty) and |error_message|
158 // will be empty. If an error occurred, |matches| will be null and
159 // |error_message| contain an error message.
160 using SelectCertificatesCallback
=
161 base::Callback
<void(scoped_ptr
<net::CertificateList
> matches
,
162 const std::string
& error_message
)>;
164 // Returns a list of certificates matching |request|.
165 // 1) all certificates that match the request (like being rooted in one of the
166 // give CAs) are determined. 2) if |interactive| is true, the currently set
167 // SelectDelegate is used to select a single certificate from these matches
168 // which will the extension will also be granted access to. 3) only
169 // certificates, that the extension has unlimited sign permission for, will be
171 // |callback| will be invoked with these certificates or an error message.
172 // Will only call back during the lifetime of this object.
173 // |web_contents| must not be null.
174 void SelectClientCertificates(
175 const platform_keys::ClientCertificateRequest
& request
,
177 const std::string
& extension_id
,
178 const SelectCertificatesCallback
& callback
,
179 content::WebContents
* web_contents
);
182 class GenerateRSAKeyTask
;
187 // Starts |task| eventually. To ensure that at most one |Task| is running at a
188 // time, it queues |task| for later execution if necessary.
189 void StartOrQueueTask(scoped_ptr
<Task
> task
);
191 // Must be called after |task| is done. |task| will be invalid after this
192 // call. This must not be called for any but the task that ran last. If any
193 // other tasks are queued (see StartOrQueueTask()), it will start the next
195 void TaskFinished(Task
* task
);
197 // Callback used by |GenerateRSAKey|.
198 // If the key generation was successful, registers the generated public key
199 // for the given extension. If any error occurs during key generation or
200 // registration, calls |callback| with an error. Otherwise, on success, calls
201 // |callback| with the public key.
202 void GeneratedKey(const std::string
& extension_id
,
203 const GenerateKeyCallback
& callback
,
204 const std::string
& public_key_spki_der
,
205 const std::string
& error_message
);
207 // Callback used by |GeneratedKey|.
208 // |public_key_spki_der| will contain the X.509 Subject Public Key Info of
209 // the generated key in DER encoding. |task| points to the finished |Task|
211 void RegisteredGeneratedKey(const GenerateKeyCallback
& callback
,
212 const std::string
& public_key_spki_der
,
215 content::BrowserContext
* browser_context_
;
216 KeyPermissions key_permissions_
;
217 scoped_ptr
<SelectDelegate
> select_delegate_
;
218 std::queue
<linked_ptr
<Task
>> tasks_
;
219 base::WeakPtrFactory
<PlatformKeysService
> weak_factory_
;
221 DISALLOW_COPY_AND_ASSIGN(PlatformKeysService
);
224 } // namespace chromeos
226 #endif // CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_PLATFORM_KEYS_SERVICE_H_