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.
167 // 2) if |client_certificates| is not null, drops all certificates that are
168 // not elements of |client_certificates|,
169 // 3) if |interactive| is true, the currently set SelectDelegate is used to
170 // select a single certificate from these matches
171 // which will the extension will also be granted access to.
172 // 4) only certificates, that the extension has unlimited sign permission for,
174 // |callback| will be invoked with these certificates or an error message.
175 // Will only call back during the lifetime of this object. |web_contents| must
177 void SelectClientCertificates(
178 const platform_keys::ClientCertificateRequest
& request
,
179 scoped_ptr
<net::CertificateList
> client_certificates
,
181 const std::string
& extension_id
,
182 const SelectCertificatesCallback
& callback
,
183 content::WebContents
* web_contents
);
186 class GenerateRSAKeyTask
;
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
199 void TaskFinished(Task
* task
);
201 // Callback used by |GenerateRSAKey|.
202 // If the key generation was successful, registers the generated public key
203 // for the given extension. If any error occurs during key generation or
204 // registration, calls |callback| with an error. Otherwise, on success, calls
205 // |callback| with the public key.
206 void GeneratedKey(const std::string
& extension_id
,
207 const GenerateKeyCallback
& callback
,
208 const std::string
& public_key_spki_der
,
209 const std::string
& error_message
);
211 // Callback used by |GeneratedKey|.
212 // |public_key_spki_der| will contain the X.509 Subject Public Key Info of
213 // the generated key in DER encoding. |task| points to the finished |Task|
215 void RegisteredGeneratedKey(const GenerateKeyCallback
& callback
,
216 const std::string
& public_key_spki_der
,
219 content::BrowserContext
* browser_context_
;
220 KeyPermissions key_permissions_
;
221 scoped_ptr
<SelectDelegate
> select_delegate_
;
222 std::queue
<linked_ptr
<Task
>> tasks_
;
223 base::WeakPtrFactory
<PlatformKeysService
> weak_factory_
;
225 DISALLOW_COPY_AND_ASSIGN(PlatformKeysService
);
228 } // namespace chromeos
230 #endif // CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_PLATFORM_KEYS_SERVICE_H_