Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: chrome/browser/chromeos/platform_keys/platform_keys_service.cc

Issue 323093003: Add the Sign-At-Most-Once restriction the enterprise.platformKeys API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h"
6
7 #include "base/base64.h"
8 #include "base/callback.h"
9 #include "base/values.h"
10 #include "chrome/browser/chromeos/platform_keys/platform_keys.h"
11 #include "chrome/browser/extensions/state_store.h"
12 #include "content/public/browser/browser_thread.h"
13
14 using content::BrowserThread;
15
16 namespace chromeos {
17
18 namespace {
19
20 const char kErrorInternal[] = "Internal Error.";
21 const char kErrorKeyNotAllowedForSigning[] =
22 "This key is not allowed for signing. Either it was used for signing "
23 "before or it was not correctly generated.";
24 const char kStateStorePlatformKeys[] = "PlatformKeys";
25
26 scoped_ptr<base::StringValue> GetPublicKeyValue(
27 const std::string& public_key_spki_der) {
28 std::string public_key_spki_der_b64;
29 base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64);
30 return make_scoped_ptr(new base::StringValue(public_key_spki_der_b64));
31 }
32
33 // Wraps |callback| into a void(bool) callback which forwards
34 // |public_key_spki_der| if |true| is passed to it.
35 void WrapGenerateKeyCallback(
36 const PlatformKeysService::GenerateKeyCallback& callback,
37 const std::string& public_key_spki_der,
38 bool success) {
39 if (success)
40 callback.Run(public_key_spki_der, std::string() /* no error */);
41 else
42 callback.Run(std::string() /* no public key */, kErrorInternal);
43 }
44
45 // Callback used by |PlatformKeysService::Sign|.
46 // Is called with the old validity of |public_key| (or false if an error
47 // occurred during reading the StateStore). If allowed, starts the actual
48 // signing operation which will call back |callback|. If not allowd, calls
eroman 2014/06/12 05:50:45 typo: allowd -> allowed
pneubeck (no reviews) 2014/06/12 09:21:37 Done.
49 // |callback| with an error.
50 void CheckValidityAndSign(const std::string& token_id,
51 const std::string& public_key,
52 const std::string& data,
53 const PlatformKeysService::SignCallback& callback,
54 Profile* profile,
55 bool key_is_valid) {
56 if (!key_is_valid) {
57 callback.Run(std::string() /* no signature */,
58 kErrorKeyNotAllowedForSigning);
59 return;
60 }
61 platform_keys::subtle::Sign(token_id, public_key, data, callback, profile);
62 }
63
64 } // namespace
65
66 PlatformKeysService::PlatformKeysService(extensions::StateStore* state_store)
67 : state_store_(state_store), weak_factory_(this) {
68 DCHECK(state_store);
69 }
70
71 PlatformKeysService::~PlatformKeysService() {
72 }
73
74 void PlatformKeysService::GenerateRSAKey(const std::string& token_id,
75 unsigned int modulus_length,
76 const std::string& extension_id,
77 const GenerateKeyCallback& callback,
78 Profile* profile) {
79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
80
81 platform_keys::subtle::GenerateRSAKey(token_id,
82 modulus_length,
83 base::Bind(&GenerateRSAKeyCallback,
84 extension_id,
85 callback,
86 weak_factory_.GetWeakPtr()),
87 profile);
88 }
89
90 void PlatformKeysService::Sign(const std::string& token_id,
91 const std::string& public_key,
92 const std::string& data,
93 const std::string& extension_id,
94 const SignCallback& callback,
95 Profile* profile) {
96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
97 ReadValidityAndInvalidateKey(extension_id,
98 public_key,
99 base::Bind(&CheckValidityAndSign,
100 token_id,
101 public_key,
102 data,
103 callback,
104 profile));
105 }
106
107 void PlatformKeysService::RegisterPublicKey(
108 const std::string& extension_id,
109 const std::string& public_key_spki_der,
110 const base::Callback<void(bool)>& callback) {
111 GetPlatformKeysOfExtension(extension_id,
112 base::Bind(&RegisterPublicKeyGotPlatformKeys,
113 extension_id,
114 public_key_spki_der,
115 callback));
116 }
117
118 void PlatformKeysService::ReadValidityAndInvalidateKey(
119 const std::string& extension_id,
120 const std::string& public_key_spki_der,
121 const base::Callback<void(bool)>& callback) {
122 GetPlatformKeysOfExtension(
123 extension_id,
124 base::Bind(&InvalidateKey, extension_id, public_key_spki_der, callback));
125 }
126
127 void PlatformKeysService::GetPlatformKeysOfExtension(
128 const std::string& extension_id,
129 const GetPlatformKeysCallback& callback) {
130 state_store_->GetExtensionValue(extension_id,
131 kStateStorePlatformKeys,
132 base::Bind(&GotPlatformKeysOfExtension,
133 extension_id,
134 weak_factory_.GetWeakPtr(),
135 callback));
136 }
137
138 // static
139 void PlatformKeysService::GenerateRSAKeyCallback(
140 const std::string& extension_id,
141 const GenerateKeyCallback& callback,
142 base::WeakPtr<PlatformKeysService> service,
143 const std::string& public_key_spki_der,
144 const std::string& error_message) {
145 if (!error_message.empty()) {
146 callback.Run(std::string() /* no public key */, error_message);
147 return;
148 }
149 base::Callback<void(bool)> wrapped_callback(
150 base::Bind(&WrapGenerateKeyCallback, callback, public_key_spki_der));
151 if (!service) {
152 LOG(ERROR) << "PlatformKeysService is already destructed.";
153 wrapped_callback.Run(false);
154 return;
155 }
156 service->RegisterPublicKey(
157 extension_id, public_key_spki_der, wrapped_callback);
158 }
159
160 // static
161 void PlatformKeysService::RegisterPublicKeyGotPlatformKeys(
162 const std::string& extension_id,
163 const std::string& public_key_spki_der,
164 const base::Callback<void(bool)>& callback,
165 base::WeakPtr<PlatformKeysService> service,
166 scoped_ptr<base::ListValue> platform_keys) {
167 if (!service) {
168 LOG(ERROR) << "PlatformKeysService is already destructed.";
169 callback.Run(false);
170 return;
171 }
172
173 if (!platform_keys) {
174 LOG(ERROR) << "Error while reading the platform keys.";
175 callback.Run(false);
176 return;
177 }
178
179 scoped_ptr<base::StringValue> key_value(
180 GetPublicKeyValue(public_key_spki_der));
181
182 DCHECK(platform_keys->end() == platform_keys->Find(*key_value))
eroman 2014/06/12 05:50:45 This is a DCHECK() because it is assumed keys are
pneubeck (no reviews) 2014/06/12 09:21:37 Yes, updated the error string for clarification.
183 << "Public key is already registered";
184 platform_keys->Append(key_value.release());
eroman 2014/06/12 05:50:45 What sort of bounds checks are done? Is it possibl
pneubeck (no reviews) 2014/06/12 09:21:36 No bounds checks so far. And yes an extension can
185
186 service->state_store_->SetExtensionValue(extension_id,
187 kStateStorePlatformKeys,
188 platform_keys.PassAs<base::Value>());
189 callback.Run(true);
190 }
191
192 // static
193 void PlatformKeysService::InvalidateKey(
194 const std::string& extension_id,
195 const std::string& public_key_spki_der,
196 const base::Callback<void(bool)>& callback,
197 base::WeakPtr<PlatformKeysService> service,
198 scoped_ptr<base::ListValue> platform_keys) {
199 if (!service) {
200 LOG(ERROR) << "PlatformKeysService is already destructed.";
201 callback.Run(false);
202 return;
203 }
204
205 scoped_ptr<base::StringValue> key_value(
206 GetPublicKeyValue(public_key_spki_der));
207
208 size_t index = 0;
209 if (!platform_keys->Remove(*key_value, &index)) {
210 // The key is not found, so it's not valid to use it for signing.
211 callback.Run(false);
212 return;
213 }
214
215 service->state_store_->SetExtensionValue(extension_id,
216 kStateStorePlatformKeys,
217 platform_keys.PassAs<base::Value>());
218 callback.Run(true);
219 }
220
221 // static
222 void PlatformKeysService::GotPlatformKeysOfExtension(
223 const std::string& extension_id,
224 base::WeakPtr<PlatformKeysService> service,
225 const GetPlatformKeysCallback& callback,
226 scoped_ptr<base::Value> value) {
227 base::ListValue* keys = NULL;
228 if (value) {
229 if (!value->GetAsList(&keys)) {
230 LOG(ERROR) << "Found a value of wrong type.";
231 value.reset();
232 }
233 } else {
234 keys = new base::ListValue;
235 value.reset(keys);
eroman 2014/06/12 05:50:45 why bother with this line, when the next one relea
pneubeck (no reviews) 2014/06/12 09:21:37 the intention was that both branches have the same
236 }
237 ignore_result(value.release());
238 callback.Run(service, make_scoped_ptr(keys));
239 }
240
241 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698