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

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: Rebased. 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_spki_der| (or false if an
47 // error occurred during reading the StateStore). If allowed, starts the actual
48 // signing operation which will call back |callback|. If not allowed, calls
49 // |callback| with an error.
50 void CheckValidityAndSign(const std::string& token_id,
51 const std::string& public_key_spki_der,
52 const std::string& data,
53 const PlatformKeysService::SignCallback& callback,
54 content::BrowserContext* browser_context,
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(
62 token_id, public_key_spki_der, data, callback, browser_context);
63 }
64
65 } // namespace
66
67 PlatformKeysService::PlatformKeysService(
68 content::BrowserContext* browser_context,
69 extensions::StateStore* state_store)
70 : browser_context_(browser_context),
71 state_store_(state_store),
72 weak_factory_(this) {
73 DCHECK(state_store);
74 }
75
76 PlatformKeysService::~PlatformKeysService() {
77 }
78
79 void PlatformKeysService::GenerateRSAKey(const std::string& token_id,
80 unsigned int modulus_length,
81 const std::string& extension_id,
82 const GenerateKeyCallback& callback) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
84
85 platform_keys::subtle::GenerateRSAKey(
86 token_id,
87 modulus_length,
88 base::Bind(&PlatformKeysService::GenerateRSAKeyCallback,
89 weak_factory_.GetWeakPtr(),
90 extension_id,
91 callback),
92 browser_context_);
93 }
94
95 void PlatformKeysService::Sign(const std::string& token_id,
96 const std::string& public_key_spki_der,
97 const std::string& data,
98 const std::string& extension_id,
99 const SignCallback& callback) {
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101 ReadValidityAndInvalidateKey(extension_id,
102 public_key_spki_der,
103 base::Bind(&CheckValidityAndSign,
104 token_id,
105 public_key_spki_der,
106 data,
107 callback,
108 browser_context_));
109 }
110
111 void PlatformKeysService::RegisterPublicKey(
112 const std::string& extension_id,
113 const std::string& public_key_spki_der,
114 const base::Callback<void(bool)>& callback) {
115 GetPlatformKeysOfExtension(
116 extension_id,
117 base::Bind(&PlatformKeysService::RegisterPublicKeyGotPlatformKeys,
118 weak_factory_.GetWeakPtr(),
119 extension_id,
120 public_key_spki_der,
121 callback));
122 }
123
124 void PlatformKeysService::ReadValidityAndInvalidateKey(
125 const std::string& extension_id,
126 const std::string& public_key_spki_der,
127 const base::Callback<void(bool)>& callback) {
128 GetPlatformKeysOfExtension(extension_id,
129 base::Bind(&PlatformKeysService::InvalidateKey,
130 weak_factory_.GetWeakPtr(),
131 extension_id,
132 public_key_spki_der,
133 callback));
134 }
135
136 void PlatformKeysService::GetPlatformKeysOfExtension(
137 const std::string& extension_id,
138 const GetPlatformKeysCallback& callback) {
139 state_store_->GetExtensionValue(
140 extension_id,
141 kStateStorePlatformKeys,
142 base::Bind(&PlatformKeysService::GotPlatformKeysOfExtension,
143 weak_factory_.GetWeakPtr(),
144 extension_id,
145 callback));
146 }
147
148 void PlatformKeysService::GenerateRSAKeyCallback(
149 const std::string& extension_id,
150 const GenerateKeyCallback& callback,
151 const std::string& public_key_spki_der,
152 const std::string& error_message) {
153 if (!error_message.empty()) {
154 callback.Run(std::string() /* no public key */, error_message);
155 return;
156 }
157 base::Callback<void(bool)> wrapped_callback(
158 base::Bind(&WrapGenerateKeyCallback, callback, public_key_spki_der));
159 RegisterPublicKey(extension_id, public_key_spki_der, wrapped_callback);
160 }
161
162 void PlatformKeysService::RegisterPublicKeyGotPlatformKeys(
163 const std::string& extension_id,
164 const std::string& public_key_spki_der,
165 const base::Callback<void(bool)>& callback,
166 scoped_ptr<base::ListValue> platform_keys) {
167 if (!platform_keys) {
168 LOG(ERROR) << "Error while reading the platform keys.";
169 callback.Run(false);
170 return;
171 }
172
173 scoped_ptr<base::StringValue> key_value(
174 GetPublicKeyValue(public_key_spki_der));
175
176 DCHECK(platform_keys->end() == platform_keys->Find(*key_value))
177 << "Keys are assumed to be generated and not to be registered multiple "
178 "times.";
179 platform_keys->Append(key_value.release());
180
181 state_store_->SetExtensionValue(extension_id,
182 kStateStorePlatformKeys,
183 platform_keys.PassAs<base::Value>());
184 callback.Run(true);
185 }
186
187 void PlatformKeysService::InvalidateKey(
188 const std::string& extension_id,
189 const std::string& public_key_spki_der,
190 const base::Callback<void(bool)>& callback,
191 scoped_ptr<base::ListValue> platform_keys) {
192 scoped_ptr<base::StringValue> key_value(
193 GetPublicKeyValue(public_key_spki_der));
194
195 size_t index = 0;
196 if (!platform_keys->Remove(*key_value, &index)) {
197 // The key is not found, so it's not valid to use it for signing.
198 callback.Run(false);
199 return;
200 }
201
202 state_store_->SetExtensionValue(extension_id,
203 kStateStorePlatformKeys,
204 platform_keys.PassAs<base::Value>());
205 callback.Run(true);
206 }
207
208 void PlatformKeysService::GotPlatformKeysOfExtension(
209 const std::string& extension_id,
210 const GetPlatformKeysCallback& callback,
211 scoped_ptr<base::Value> value) {
212 if (!value)
213 value.reset(new base::ListValue);
214
215 base::ListValue* keys = NULL;
216 if (!value->GetAsList(&keys)) {
217 LOG(ERROR) << "Found a value of wrong type.";
218 value.reset();
219 }
220 ignore_result(value.release());
221 callback.Run(make_scoped_ptr(keys));
222 }
223
224 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698