blob: 9f4727022acd6c8d13e2b23a15f00894db7921c2 [file] [log] [blame]
[email protected]cf5d32e52014-03-07 18:00:081// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]408699c2013-07-17 21:23:162// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
erg56f12322015-04-17 00:51:485#include "components/webcrypto/webcrypto_impl.h"
[email protected]408699c2013-07-17 21:23:166
avi51ba3e692015-12-26 17:30:507#include <limits.h>
avi5dd91f82015-12-25 22:30:468#include <stdint.h>
9
dcheng7036d1e52016-04-21 23:13:0310#include <memory>
11
[email protected]88be98562014-04-30 11:18:5912#include "base/bind.h"
13#include "base/lazy_instance.h"
14#include "base/location.h"
[email protected]c1b944a2013-10-23 06:33:2115#include "base/logging.h"
[email protected]88be98562014-04-30 11:18:5916#include "base/single_thread_task_runner.h"
17#include "base/task_runner.h"
[email protected]88be98562014-04-30 11:18:5918#include "base/threading/sequenced_worker_pool.h"
gab7966d312016-05-11 20:35:0119#include "base/threading/thread_task_runner_handle.h"
[email protected]88be98562014-04-30 11:18:5920#include "base/threading/worker_pool.h"
erg56f12322015-04-17 00:51:4821#include "components/webcrypto/algorithm_dispatch.h"
22#include "components/webcrypto/crypto_data.h"
23#include "components/webcrypto/generate_key_result.h"
24#include "components/webcrypto/status.h"
[email protected]8238bb1c2014-02-26 15:16:2525#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
[email protected]cf5d32e52014-03-07 18:00:0826#include "third_party/WebKit/public/platform/WebString.h"
[email protected]408699c2013-07-17 21:23:1627
erg56f12322015-04-17 00:51:4828namespace webcrypto {
[email protected]408699c2013-07-17 21:23:1629
[email protected]cca897482014-01-30 22:40:1930using webcrypto::Status;
31
[email protected]043cf1d32013-11-02 13:27:3032namespace {
33
[email protected]88be98562014-04-30 11:18:5934// ---------------------
35// Threading
36// ---------------------
37//
38// WebCrypto operations can be slow. For instance generating an RSA key can
eroman984ead6c2016-06-23 00:25:2539// take seconds.
[email protected]88be98562014-04-30 11:18:5940//
41// The strategy used here is to run a sequenced worker pool for all WebCrypto
eromana895fed2014-11-08 03:10:2542// operations (except structured cloning). This same pool is also used by
43// requests started from Blink Web Workers.
[email protected]88be98562014-04-30 11:18:5944//
45// A few notes to keep in mind:
46//
eroman984ead6c2016-06-23 00:25:2547// * PostTaskAndReply() is not used because of how it handles failures -- it
48// leaks the callback when failing to post back to the origin thread.
[email protected]88be98562014-04-30 11:18:5949//
eroman984ead6c2016-06-23 00:25:2550// This is a problem since WebCrypto may be called from WebWorker threads,
51// which may be aborted at any time. Leaking would be undesirable, and
52// reachable in practice.
[email protected]88be98562014-04-30 11:18:5953//
54// * blink::WebArrayBuffer is NOT threadsafe, and should therefore be allocated
eroman984ead6c2016-06-23 00:25:2555// only on the target Blink thread.
[email protected]88be98562014-04-30 11:18:5956//
57// TODO(eroman): Is there any way around this? Copying the result between
58// threads is silly.
59//
eroman984ead6c2016-06-23 00:25:2560// * WebCryptoAlgorithm and WebCryptoKey are threadsafe, by virtue of being
61// immutable. Internally asymmetric WebCryptoKeys wrap BoringSSL's EVP_PKEY.
62// These are safe to use for BoringSSL operations across threads, provided
63// the internals of the EVP_PKEY are not mutated (they never should be
64// following ImportKey()).
[email protected]88be98562014-04-30 11:18:5965//
66// * blink::WebCryptoResult is not threadsafe and should only be operated on
67// the target Blink thread. HOWEVER, it is safe to delete it from any thread.
68// This can happen if by the time the operation has completed in the crypto
69// worker pool, the Blink worker thread that initiated the request is gone.
70// Posting back to the origin thread will fail, and the WebCryptoResult will
71// be deleted while running in the crypto worker pool.
72class CryptoThreadPool {
73 public:
74 CryptoThreadPool()
75 : worker_pool_(new base::SequencedWorkerPool(1, "WebCrypto")),
76 task_runner_(worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
77 worker_pool_->GetSequenceToken(),
78 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) {}
79
80 static bool PostTask(const tracked_objects::Location& from_here,
81 const base::Closure& task);
82
83 private:
84 scoped_refptr<base::SequencedWorkerPool> worker_pool_;
85 scoped_refptr<base::SequencedTaskRunner> task_runner_;
86};
87
88base::LazyInstance<CryptoThreadPool>::Leaky crypto_thread_pool =
89 LAZY_INSTANCE_INITIALIZER;
90
91bool CryptoThreadPool::PostTask(const tracked_objects::Location& from_here,
92 const base::Closure& task) {
93 return crypto_thread_pool.Get().task_runner_->PostTask(from_here, task);
94}
95
96void CompleteWithThreadPoolError(blink::WebCryptoResult* result) {
97 result->completeWithError(blink::WebCryptoErrorTypeOperation,
98 "Failed posting to crypto worker pool");
99}
100
[email protected]cca897482014-01-30 22:40:19101void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
102 DCHECK(status.IsError());
[email protected]c5039362014-04-28 19:10:34103
[email protected]c5039362014-04-28 19:10:34104 result->completeWithError(status.error_type(),
105 blink::WebString::fromUTF8(status.error_details()));
[email protected]cca897482014-01-30 22:40:19106}
107
[email protected]88be98562014-04-30 11:18:59108void CompleteWithBufferOrError(const Status& status,
[email protected]53b6c9d22014-07-19 05:08:38109 const std::vector<uint8_t>& buffer,
[email protected]88be98562014-04-30 11:18:59110 blink::WebCryptoResult* result) {
111 if (status.IsError()) {
112 CompleteWithError(status, result);
113 } else {
114 if (buffer.size() > UINT_MAX) {
115 // WebArrayBuffers have a smaller range than std::vector<>, so
116 // theoretically this could overflow.
117 CompleteWithError(Status::ErrorUnexpected(), result);
118 } else {
davidbenaa62f382015-11-20 22:10:01119 result->completeWithBuffer(buffer.data(),
brettw690c96672015-04-21 16:19:54120 static_cast<unsigned int>(buffer.size()));
[email protected]88be98562014-04-30 11:18:59121 }
122 }
123}
124
125void CompleteWithKeyOrError(const Status& status,
126 const blink::WebCryptoKey& key,
127 blink::WebCryptoResult* result) {
128 if (status.IsError()) {
129 CompleteWithError(status, result);
130 } else {
131 result->completeWithKey(key);
132 }
133}
134
Sadrul Habib Chowdhury3a4b2d12015-02-04 01:10:42135// Gets a task runner for the current thread.
[email protected]88be98562014-04-30 11:18:59136scoped_refptr<base::TaskRunner> GetCurrentBlinkThread() {
Sadrul Habib Chowdhury3a4b2d12015-02-04 01:10:42137 DCHECK(base::ThreadTaskRunnerHandle::IsSet());
138 return base::ThreadTaskRunnerHandle::Get();
[email protected]88be98562014-04-30 11:18:59139}
140
141// --------------------------------------------------------------------
142// State
143// --------------------------------------------------------------------
144//
145// Explicit state classes are used rather than base::Bind(). This is done
146// both for clarity, but also to avoid extraneous allocations for things
147// like passing buffers and result objects between threads.
148//
149// BaseState is the base class common to all of the async operations, and
150// keeps track of the thread to complete on, the error state, and the
151// callback into Blink.
152//
153// Ownership of the State object is passed between the crypto thread and the
154// Blink thread. Under normal completion it is destroyed on the Blink thread.
155// However it may also be destroyed on the crypto thread if the Blink thread
156// has vanished (which can happen for Blink web worker threads).
157
158struct BaseState {
159 explicit BaseState(const blink::WebCryptoResult& result)
160 : origin_thread(GetCurrentBlinkThread()), result(result) {}
161
eroman38bb4bd2014-11-24 23:47:06162 bool cancelled() { return result.cancelled(); }
[email protected]345bd202014-06-19 04:51:16163
[email protected]88be98562014-04-30 11:18:59164 scoped_refptr<base::TaskRunner> origin_thread;
165
166 webcrypto::Status status;
167 blink::WebCryptoResult result;
168
169 protected:
170 // Since there is no virtual destructor, must not delete directly as a
171 // BaseState.
172 ~BaseState() {}
173};
174
175struct EncryptState : public BaseState {
176 EncryptState(const blink::WebCryptoAlgorithm& algorithm,
177 const blink::WebCryptoKey& key,
178 const unsigned char* data,
179 unsigned int data_size,
180 const blink::WebCryptoResult& result)
181 : BaseState(result),
182 algorithm(algorithm),
183 key(key),
184 data(data, data + data_size) {}
185
186 const blink::WebCryptoAlgorithm algorithm;
187 const blink::WebCryptoKey key;
[email protected]53b6c9d22014-07-19 05:08:38188 const std::vector<uint8_t> data;
[email protected]88be98562014-04-30 11:18:59189
[email protected]53b6c9d22014-07-19 05:08:38190 std::vector<uint8_t> buffer;
[email protected]88be98562014-04-30 11:18:59191};
192
193typedef EncryptState DecryptState;
194typedef EncryptState DigestState;
195
196struct GenerateKeyState : public BaseState {
197 GenerateKeyState(const blink::WebCryptoAlgorithm& algorithm,
198 bool extractable,
eroman0e1d34e2014-10-21 19:13:31199 blink::WebCryptoKeyUsageMask usages,
[email protected]88be98562014-04-30 11:18:59200 const blink::WebCryptoResult& result)
201 : BaseState(result),
202 algorithm(algorithm),
203 extractable(extractable),
eroman0e1d34e2014-10-21 19:13:31204 usages(usages) {}
[email protected]88be98562014-04-30 11:18:59205
206 const blink::WebCryptoAlgorithm algorithm;
207 const bool extractable;
eroman0e1d34e2014-10-21 19:13:31208 const blink::WebCryptoKeyUsageMask usages;
[email protected]88be98562014-04-30 11:18:59209
eroman9b747eaf2014-10-18 22:03:28210 webcrypto::GenerateKeyResult generate_key_result;
[email protected]88be98562014-04-30 11:18:59211};
212
213struct ImportKeyState : public BaseState {
214 ImportKeyState(blink::WebCryptoKeyFormat format,
215 const unsigned char* key_data,
216 unsigned int key_data_size,
217 const blink::WebCryptoAlgorithm& algorithm,
218 bool extractable,
eroman0e1d34e2014-10-21 19:13:31219 blink::WebCryptoKeyUsageMask usages,
[email protected]88be98562014-04-30 11:18:59220 const blink::WebCryptoResult& result)
221 : BaseState(result),
222 format(format),
223 key_data(key_data, key_data + key_data_size),
224 algorithm(algorithm),
225 extractable(extractable),
eroman0e1d34e2014-10-21 19:13:31226 usages(usages) {}
[email protected]88be98562014-04-30 11:18:59227
228 const blink::WebCryptoKeyFormat format;
[email protected]53b6c9d22014-07-19 05:08:38229 const std::vector<uint8_t> key_data;
[email protected]88be98562014-04-30 11:18:59230 const blink::WebCryptoAlgorithm algorithm;
231 const bool extractable;
eroman0e1d34e2014-10-21 19:13:31232 const blink::WebCryptoKeyUsageMask usages;
[email protected]88be98562014-04-30 11:18:59233
234 blink::WebCryptoKey key;
235};
236
237struct ExportKeyState : public BaseState {
238 ExportKeyState(blink::WebCryptoKeyFormat format,
239 const blink::WebCryptoKey& key,
240 const blink::WebCryptoResult& result)
241 : BaseState(result), format(format), key(key) {}
242
243 const blink::WebCryptoKeyFormat format;
244 const blink::WebCryptoKey key;
245
[email protected]53b6c9d22014-07-19 05:08:38246 std::vector<uint8_t> buffer;
[email protected]88be98562014-04-30 11:18:59247};
248
249typedef EncryptState SignState;
250
251struct VerifySignatureState : public BaseState {
252 VerifySignatureState(const blink::WebCryptoAlgorithm& algorithm,
253 const blink::WebCryptoKey& key,
254 const unsigned char* signature,
255 unsigned int signature_size,
256 const unsigned char* data,
257 unsigned int data_size,
258 const blink::WebCryptoResult& result)
259 : BaseState(result),
260 algorithm(algorithm),
261 key(key),
262 signature(signature, signature + signature_size),
263 data(data, data + data_size),
264 verify_result(false) {}
265
266 const blink::WebCryptoAlgorithm algorithm;
267 const blink::WebCryptoKey key;
[email protected]53b6c9d22014-07-19 05:08:38268 const std::vector<uint8_t> signature;
269 const std::vector<uint8_t> data;
[email protected]88be98562014-04-30 11:18:59270
271 bool verify_result;
272};
273
274struct WrapKeyState : public BaseState {
275 WrapKeyState(blink::WebCryptoKeyFormat format,
276 const blink::WebCryptoKey& key,
277 const blink::WebCryptoKey& wrapping_key,
278 const blink::WebCryptoAlgorithm& wrap_algorithm,
279 const blink::WebCryptoResult& result)
280 : BaseState(result),
281 format(format),
282 key(key),
283 wrapping_key(wrapping_key),
284 wrap_algorithm(wrap_algorithm) {}
285
286 const blink::WebCryptoKeyFormat format;
287 const blink::WebCryptoKey key;
288 const blink::WebCryptoKey wrapping_key;
289 const blink::WebCryptoAlgorithm wrap_algorithm;
290
[email protected]53b6c9d22014-07-19 05:08:38291 std::vector<uint8_t> buffer;
[email protected]88be98562014-04-30 11:18:59292};
293
294struct UnwrapKeyState : public BaseState {
295 UnwrapKeyState(blink::WebCryptoKeyFormat format,
296 const unsigned char* wrapped_key,
297 unsigned wrapped_key_size,
298 const blink::WebCryptoKey& wrapping_key,
299 const blink::WebCryptoAlgorithm& unwrap_algorithm,
300 const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
301 bool extractable,
302 blink::WebCryptoKeyUsageMask usages,
303 const blink::WebCryptoResult& result)
304 : BaseState(result),
305 format(format),
306 wrapped_key(wrapped_key, wrapped_key + wrapped_key_size),
307 wrapping_key(wrapping_key),
308 unwrap_algorithm(unwrap_algorithm),
309 unwrapped_key_algorithm(unwrapped_key_algorithm),
310 extractable(extractable),
eroman7b9591ab2014-10-21 17:13:01311 usages(usages) {}
[email protected]88be98562014-04-30 11:18:59312
313 const blink::WebCryptoKeyFormat format;
[email protected]53b6c9d22014-07-19 05:08:38314 const std::vector<uint8_t> wrapped_key;
[email protected]88be98562014-04-30 11:18:59315 const blink::WebCryptoKey wrapping_key;
316 const blink::WebCryptoAlgorithm unwrap_algorithm;
317 const blink::WebCryptoAlgorithm unwrapped_key_algorithm;
318 const bool extractable;
319 const blink::WebCryptoKeyUsageMask usages;
320
321 blink::WebCryptoKey unwrapped_key;
322};
323
eroman1499b4942014-11-26 19:59:53324struct DeriveBitsState : public BaseState {
325 DeriveBitsState(const blink::WebCryptoAlgorithm& algorithm,
326 const blink::WebCryptoKey& base_key,
327 unsigned int length_bits,
328 const blink::WebCryptoResult& result)
329 : BaseState(result),
330 algorithm(algorithm),
331 base_key(base_key),
332 length_bits(length_bits) {}
333
334 const blink::WebCryptoAlgorithm algorithm;
335 const blink::WebCryptoKey base_key;
336 const unsigned int length_bits;
337
338 std::vector<uint8_t> derived_bytes;
339};
340
eroman20bf4c3c2014-12-12 17:22:37341struct DeriveKeyState : public BaseState {
342 DeriveKeyState(const blink::WebCryptoAlgorithm& algorithm,
343 const blink::WebCryptoKey& base_key,
344 const blink::WebCryptoAlgorithm& import_algorithm,
345 const blink::WebCryptoAlgorithm& key_length_algorithm,
346 bool extractable,
347 blink::WebCryptoKeyUsageMask usages,
348 const blink::WebCryptoResult& result)
349 : BaseState(result),
350 algorithm(algorithm),
351 base_key(base_key),
352 import_algorithm(import_algorithm),
353 key_length_algorithm(key_length_algorithm),
354 extractable(extractable),
355 usages(usages) {}
356
357 const blink::WebCryptoAlgorithm algorithm;
358 const blink::WebCryptoKey base_key;
359 const blink::WebCryptoAlgorithm import_algorithm;
360 const blink::WebCryptoAlgorithm key_length_algorithm;
361 bool extractable;
362 blink::WebCryptoKeyUsageMask usages;
363
364 blink::WebCryptoKey derived_key;
365};
366
[email protected]88be98562014-04-30 11:18:59367// --------------------------------------------------------------------
368// Wrapper functions
369// --------------------------------------------------------------------
370//
371// * The methods named Do*() run on the crypto thread.
372// * The methods named Do*Reply() run on the target Blink thread
373
dcheng7036d1e52016-04-21 23:13:03374void DoEncryptReply(std::unique_ptr<EncryptState> state) {
[email protected]88be98562014-04-30 11:18:59375 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
376}
377
dcheng7036d1e52016-04-21 23:13:03378void DoEncrypt(std::unique_ptr<EncryptState> passed_state) {
[email protected]88be98562014-04-30 11:18:59379 EncryptState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16380 if (state->cancelled())
381 return;
eroman38bb4bd2014-11-24 23:47:06382 state->status =
383 webcrypto::Encrypt(state->algorithm, state->key,
384 webcrypto::CryptoData(state->data), &state->buffer);
[email protected]88be98562014-04-30 11:18:59385 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20386 FROM_HERE, base::Bind(DoEncryptReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59387}
388
dcheng7036d1e52016-04-21 23:13:03389void DoDecryptReply(std::unique_ptr<DecryptState> state) {
[email protected]88be98562014-04-30 11:18:59390 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
391}
392
dcheng7036d1e52016-04-21 23:13:03393void DoDecrypt(std::unique_ptr<DecryptState> passed_state) {
[email protected]88be98562014-04-30 11:18:59394 DecryptState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16395 if (state->cancelled())
396 return;
eroman38bb4bd2014-11-24 23:47:06397 state->status =
398 webcrypto::Decrypt(state->algorithm, state->key,
399 webcrypto::CryptoData(state->data), &state->buffer);
[email protected]88be98562014-04-30 11:18:59400 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20401 FROM_HERE, base::Bind(DoDecryptReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59402}
403
dcheng7036d1e52016-04-21 23:13:03404void DoDigestReply(std::unique_ptr<DigestState> state) {
[email protected]88be98562014-04-30 11:18:59405 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
406}
407
dcheng7036d1e52016-04-21 23:13:03408void DoDigest(std::unique_ptr<DigestState> passed_state) {
[email protected]88be98562014-04-30 11:18:59409 DigestState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16410 if (state->cancelled())
411 return;
[email protected]88be98562014-04-30 11:18:59412 state->status = webcrypto::Digest(
413 state->algorithm, webcrypto::CryptoData(state->data), &state->buffer);
414 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20415 FROM_HERE, base::Bind(DoDigestReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59416}
417
dcheng7036d1e52016-04-21 23:13:03418void DoGenerateKeyReply(std::unique_ptr<GenerateKeyState> state) {
[email protected]88be98562014-04-30 11:18:59419 if (state->status.IsError()) {
420 CompleteWithError(state->status, &state->result);
421 } else {
eroman9b747eaf2014-10-18 22:03:28422 state->generate_key_result.Complete(&state->result);
[email protected]88be98562014-04-30 11:18:59423 }
424}
425
dcheng7036d1e52016-04-21 23:13:03426void DoGenerateKey(std::unique_ptr<GenerateKeyState> passed_state) {
[email protected]88be98562014-04-30 11:18:59427 GenerateKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16428 if (state->cancelled())
429 return;
eroman38bb4bd2014-11-24 23:47:06430 state->status =
431 webcrypto::GenerateKey(state->algorithm, state->extractable,
432 state->usages, &state->generate_key_result);
[email protected]88be98562014-04-30 11:18:59433 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20434 FROM_HERE, base::Bind(DoGenerateKeyReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59435}
436
dcheng7036d1e52016-04-21 23:13:03437void DoImportKeyReply(std::unique_ptr<ImportKeyState> state) {
[email protected]88be98562014-04-30 11:18:59438 CompleteWithKeyOrError(state->status, state->key, &state->result);
439}
440
dcheng7036d1e52016-04-21 23:13:03441void DoImportKey(std::unique_ptr<ImportKeyState> passed_state) {
[email protected]88be98562014-04-30 11:18:59442 ImportKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16443 if (state->cancelled())
444 return;
eroman38bb4bd2014-11-24 23:47:06445 state->status = webcrypto::ImportKey(
446 state->format, webcrypto::CryptoData(state->key_data), state->algorithm,
447 state->extractable, state->usages, &state->key);
[email protected]88be98562014-04-30 11:18:59448 if (state->status.IsSuccess()) {
449 DCHECK(state->key.handle());
450 DCHECK(!state->key.algorithm().isNull());
451 DCHECK_EQ(state->extractable, state->key.extractable());
452 }
453
454 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20455 FROM_HERE, base::Bind(DoImportKeyReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59456}
457
dcheng7036d1e52016-04-21 23:13:03458void DoExportKeyReply(std::unique_ptr<ExportKeyState> state) {
[email protected]b7deaa082014-06-17 22:24:37459 if (state->format != blink::WebCryptoKeyFormatJwk) {
460 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
461 return;
462 }
463
464 if (state->status.IsError()) {
465 CompleteWithError(state->status, &state->result);
466 } else {
467 state->result.completeWithJson(
davidbenaa62f382015-11-20 22:10:01468 reinterpret_cast<const char*>(state->buffer.data()),
brettw690c96672015-04-21 16:19:54469 static_cast<unsigned int>(state->buffer.size()));
[email protected]b7deaa082014-06-17 22:24:37470 }
[email protected]88be98562014-04-30 11:18:59471}
472
dcheng7036d1e52016-04-21 23:13:03473void DoExportKey(std::unique_ptr<ExportKeyState> passed_state) {
[email protected]88be98562014-04-30 11:18:59474 ExportKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16475 if (state->cancelled())
476 return;
[email protected]88be98562014-04-30 11:18:59477 state->status =
478 webcrypto::ExportKey(state->format, state->key, &state->buffer);
479 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20480 FROM_HERE, base::Bind(DoExportKeyReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59481}
482
dcheng7036d1e52016-04-21 23:13:03483void DoSignReply(std::unique_ptr<SignState> state) {
[email protected]88be98562014-04-30 11:18:59484 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
485}
486
dcheng7036d1e52016-04-21 23:13:03487void DoSign(std::unique_ptr<SignState> passed_state) {
[email protected]88be98562014-04-30 11:18:59488 SignState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16489 if (state->cancelled())
490 return;
eroman38bb4bd2014-11-24 23:47:06491 state->status =
492 webcrypto::Sign(state->algorithm, state->key,
493 webcrypto::CryptoData(state->data), &state->buffer);
[email protected]88be98562014-04-30 11:18:59494
495 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20496 FROM_HERE, base::Bind(DoSignReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59497}
498
dcheng7036d1e52016-04-21 23:13:03499void DoVerifyReply(std::unique_ptr<VerifySignatureState> state) {
[email protected]88be98562014-04-30 11:18:59500 if (state->status.IsError()) {
501 CompleteWithError(state->status, &state->result);
502 } else {
503 state->result.completeWithBoolean(state->verify_result);
504 }
505}
506
dcheng7036d1e52016-04-21 23:13:03507void DoVerify(std::unique_ptr<VerifySignatureState> passed_state) {
[email protected]88be98562014-04-30 11:18:59508 VerifySignatureState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16509 if (state->cancelled())
510 return;
eroman38bb4bd2014-11-24 23:47:06511 state->status = webcrypto::Verify(
512 state->algorithm, state->key, webcrypto::CryptoData(state->signature),
513 webcrypto::CryptoData(state->data), &state->verify_result);
[email protected]88be98562014-04-30 11:18:59514
515 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20516 FROM_HERE, base::Bind(DoVerifyReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59517}
518
dcheng7036d1e52016-04-21 23:13:03519void DoWrapKeyReply(std::unique_ptr<WrapKeyState> state) {
[email protected]88be98562014-04-30 11:18:59520 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
521}
522
dcheng7036d1e52016-04-21 23:13:03523void DoWrapKey(std::unique_ptr<WrapKeyState> passed_state) {
[email protected]88be98562014-04-30 11:18:59524 WrapKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16525 if (state->cancelled())
526 return;
eroman38bb4bd2014-11-24 23:47:06527 state->status =
528 webcrypto::WrapKey(state->format, state->key, state->wrapping_key,
529 state->wrap_algorithm, &state->buffer);
[email protected]88be98562014-04-30 11:18:59530
531 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20532 FROM_HERE, base::Bind(DoWrapKeyReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59533}
534
dcheng7036d1e52016-04-21 23:13:03535void DoUnwrapKeyReply(std::unique_ptr<UnwrapKeyState> state) {
[email protected]88be98562014-04-30 11:18:59536 CompleteWithKeyOrError(state->status, state->unwrapped_key, &state->result);
537}
538
dcheng7036d1e52016-04-21 23:13:03539void DoUnwrapKey(std::unique_ptr<UnwrapKeyState> passed_state) {
[email protected]88be98562014-04-30 11:18:59540 UnwrapKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16541 if (state->cancelled())
542 return;
eroman38bb4bd2014-11-24 23:47:06543 state->status = webcrypto::UnwrapKey(
544 state->format, webcrypto::CryptoData(state->wrapped_key),
545 state->wrapping_key, state->unwrap_algorithm,
546 state->unwrapped_key_algorithm, state->extractable, state->usages,
547 &state->unwrapped_key);
[email protected]88be98562014-04-30 11:18:59548
549 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20550 FROM_HERE, base::Bind(DoUnwrapKeyReply, base::Passed(&passed_state)));
[email protected]88be98562014-04-30 11:18:59551}
552
dcheng7036d1e52016-04-21 23:13:03553void DoDeriveBitsReply(std::unique_ptr<DeriveBitsState> state) {
eroman1499b4942014-11-26 19:59:53554 CompleteWithBufferOrError(state->status, state->derived_bytes,
555 &state->result);
556}
557
dcheng7036d1e52016-04-21 23:13:03558void DoDeriveBits(std::unique_ptr<DeriveBitsState> passed_state) {
eroman1499b4942014-11-26 19:59:53559 DeriveBitsState* state = passed_state.get();
560 if (state->cancelled())
561 return;
562 state->status =
563 webcrypto::DeriveBits(state->algorithm, state->base_key,
564 state->length_bits, &state->derived_bytes);
565 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20566 FROM_HERE, base::Bind(DoDeriveBitsReply, base::Passed(&passed_state)));
eroman1499b4942014-11-26 19:59:53567}
568
dcheng7036d1e52016-04-21 23:13:03569void DoDeriveKeyReply(std::unique_ptr<DeriveKeyState> state) {
eroman20bf4c3c2014-12-12 17:22:37570 CompleteWithKeyOrError(state->status, state->derived_key, &state->result);
571}
572
dcheng7036d1e52016-04-21 23:13:03573void DoDeriveKey(std::unique_ptr<DeriveKeyState> passed_state) {
eroman20bf4c3c2014-12-12 17:22:37574 DeriveKeyState* state = passed_state.get();
575 if (state->cancelled())
576 return;
577 state->status = webcrypto::DeriveKey(
578 state->algorithm, state->base_key, state->import_algorithm,
579 state->key_length_algorithm, state->extractable, state->usages,
580 &state->derived_key);
581 state->origin_thread->PostTask(
dcheng0917ec42015-11-19 07:00:20582 FROM_HERE, base::Bind(DoDeriveKeyReply, base::Passed(&passed_state)));
eroman20bf4c3c2014-12-12 17:22:37583}
584
[email protected]043cf1d32013-11-02 13:27:30585} // namespace
586
[email protected]88be98562014-04-30 11:18:59587WebCryptoImpl::WebCryptoImpl() {
[email protected]88be98562014-04-30 11:18:59588}
[email protected]7e4c36f2013-09-12 06:10:19589
[email protected]88be98562014-04-30 11:18:59590WebCryptoImpl::~WebCryptoImpl() {
591}
[email protected]04166f82014-02-19 06:11:04592
[email protected]a60326552014-02-19 22:58:24593void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm& algorithm,
594 const blink::WebCryptoKey& key,
595 const unsigned char* data,
596 unsigned int data_size,
597 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34598 DCHECK(!algorithm.isNull());
[email protected]88be98562014-04-30 11:18:59599
dcheng7036d1e52016-04-21 23:13:03600 std::unique_ptr<EncryptState> state(
[email protected]88be98562014-04-30 11:18:59601 new EncryptState(algorithm, key, data, data_size, result));
dcheng0917ec42015-11-19 07:00:20602 if (!CryptoThreadPool::PostTask(
603 FROM_HERE, base::Bind(DoEncrypt, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59604 CompleteWithThreadPoolError(&result);
605 }
[email protected]a2a06c732013-09-27 10:50:54606}
607
[email protected]a60326552014-02-19 22:58:24608void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm& algorithm,
609 const blink::WebCryptoKey& key,
610 const unsigned char* data,
611 unsigned int data_size,
612 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34613 DCHECK(!algorithm.isNull());
[email protected]88be98562014-04-30 11:18:59614
dcheng7036d1e52016-04-21 23:13:03615 std::unique_ptr<DecryptState> state(
[email protected]88be98562014-04-30 11:18:59616 new DecryptState(algorithm, key, data, data_size, result));
dcheng0917ec42015-11-19 07:00:20617 if (!CryptoThreadPool::PostTask(
618 FROM_HERE, base::Bind(DoDecrypt, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59619 CompleteWithThreadPoolError(&result);
620 }
[email protected]868085a92013-10-01 00:42:30621}
622
[email protected]a60326552014-02-19 22:58:24623void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm,
624 const unsigned char* data,
625 unsigned int data_size,
626 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34627 DCHECK(!algorithm.isNull());
[email protected]88be98562014-04-30 11:18:59628
dcheng7036d1e52016-04-21 23:13:03629 std::unique_ptr<DigestState> state(new DigestState(
[email protected]88be98562014-04-30 11:18:59630 algorithm, blink::WebCryptoKey::createNull(), data, data_size, result));
631 if (!CryptoThreadPool::PostTask(FROM_HERE,
dcheng0917ec42015-11-19 07:00:20632 base::Bind(DoDigest, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59633 CompleteWithThreadPoolError(&result);
634 }
[email protected]408699c2013-07-17 21:23:16635}
636
[email protected]a60326552014-02-19 22:58:24637void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm,
638 bool extractable,
eroman0e1d34e2014-10-21 19:13:31639 blink::WebCryptoKeyUsageMask usages,
[email protected]a60326552014-02-19 22:58:24640 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34641 DCHECK(!algorithm.isNull());
[email protected]88be98562014-04-30 11:18:59642
dcheng7036d1e52016-04-21 23:13:03643 std::unique_ptr<GenerateKeyState> state(
eroman0e1d34e2014-10-21 19:13:31644 new GenerateKeyState(algorithm, extractable, usages, result));
dcheng0917ec42015-11-19 07:00:20645 if (!CryptoThreadPool::PostTask(
646 FROM_HERE, base::Bind(DoGenerateKey, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59647 CompleteWithThreadPoolError(&result);
[email protected]dfae8ab2013-10-10 19:45:06648 }
649}
650
[email protected]c7a94682014-03-20 22:58:40651void WebCryptoImpl::importKey(blink::WebCryptoKeyFormat format,
652 const unsigned char* key_data,
653 unsigned int key_data_size,
654 const blink::WebCryptoAlgorithm& algorithm,
655 bool extractable,
eroman0e1d34e2014-10-21 19:13:31656 blink::WebCryptoKeyUsageMask usages,
[email protected]c7a94682014-03-20 22:58:40657 blink::WebCryptoResult result) {
dcheng7036d1e52016-04-21 23:13:03658 std::unique_ptr<ImportKeyState> state(new ImportKeyState(
eroman0e1d34e2014-10-21 19:13:31659 format, key_data, key_data_size, algorithm, extractable, usages, result));
dcheng0917ec42015-11-19 07:00:20660 if (!CryptoThreadPool::PostTask(
661 FROM_HERE, base::Bind(DoImportKey, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59662 CompleteWithThreadPoolError(&result);
[email protected]cca897482014-01-30 22:40:19663 }
[email protected]1c879bc92013-09-18 07:45:32664}
665
[email protected]a60326552014-02-19 22:58:24666void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format,
667 const blink::WebCryptoKey& key,
668 blink::WebCryptoResult result) {
dcheng7036d1e52016-04-21 23:13:03669 std::unique_ptr<ExportKeyState> state(
670 new ExportKeyState(format, key, result));
dcheng0917ec42015-11-19 07:00:20671 if (!CryptoThreadPool::PostTask(
672 FROM_HERE, base::Bind(DoExportKey, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59673 CompleteWithThreadPoolError(&result);
674 }
[email protected]e9b2c102013-11-26 04:26:33675}
676
[email protected]a60326552014-02-19 22:58:24677void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm& algorithm,
678 const blink::WebCryptoKey& key,
679 const unsigned char* data,
680 unsigned int data_size,
681 blink::WebCryptoResult result) {
dcheng7036d1e52016-04-21 23:13:03682 std::unique_ptr<SignState> state(
[email protected]88be98562014-04-30 11:18:59683 new SignState(algorithm, key, data, data_size, result));
684 if (!CryptoThreadPool::PostTask(FROM_HERE,
dcheng0917ec42015-11-19 07:00:20685 base::Bind(DoSign, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59686 CompleteWithThreadPoolError(&result);
687 }
[email protected]1c879bc92013-09-18 07:45:32688}
689
[email protected]a60326552014-02-19 22:58:24690void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm& algorithm,
691 const blink::WebCryptoKey& key,
692 const unsigned char* signature,
693 unsigned int signature_size,
694 const unsigned char* data,
695 unsigned int data_size,
696 blink::WebCryptoResult result) {
dcheng7036d1e52016-04-21 23:13:03697 std::unique_ptr<VerifySignatureState> state(new VerifySignatureState(
[email protected]88be98562014-04-30 11:18:59698 algorithm, key, signature, signature_size, data, data_size, result));
699 if (!CryptoThreadPool::PostTask(FROM_HERE,
dcheng0917ec42015-11-19 07:00:20700 base::Bind(DoVerify, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59701 CompleteWithThreadPoolError(&result);
702 }
[email protected]3ed00262013-09-26 22:28:10703}
704
[email protected]baa92842014-03-25 01:07:38705void WebCryptoImpl::wrapKey(blink::WebCryptoKeyFormat format,
706 const blink::WebCryptoKey& key,
707 const blink::WebCryptoKey& wrapping_key,
708 const blink::WebCryptoAlgorithm& wrap_algorithm,
709 blink::WebCryptoResult result) {
dcheng7036d1e52016-04-21 23:13:03710 std::unique_ptr<WrapKeyState> state(
[email protected]88be98562014-04-30 11:18:59711 new WrapKeyState(format, key, wrapping_key, wrap_algorithm, result));
dcheng0917ec42015-11-19 07:00:20712 if (!CryptoThreadPool::PostTask(
713 FROM_HERE, base::Bind(DoWrapKey, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59714 CompleteWithThreadPoolError(&result);
715 }
[email protected]baa92842014-03-25 01:07:38716}
717
718void WebCryptoImpl::unwrapKey(
719 blink::WebCryptoKeyFormat format,
720 const unsigned char* wrapped_key,
721 unsigned wrapped_key_size,
722 const blink::WebCryptoKey& wrapping_key,
723 const blink::WebCryptoAlgorithm& unwrap_algorithm,
724 const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
725 bool extractable,
726 blink::WebCryptoKeyUsageMask usages,
727 blink::WebCryptoResult result) {
dcheng7036d1e52016-04-21 23:13:03728 std::unique_ptr<UnwrapKeyState> state(new UnwrapKeyState(
eroman38bb4bd2014-11-24 23:47:06729 format, wrapped_key, wrapped_key_size, wrapping_key, unwrap_algorithm,
730 unwrapped_key_algorithm, extractable, usages, result));
dcheng0917ec42015-11-19 07:00:20731 if (!CryptoThreadPool::PostTask(
732 FROM_HERE, base::Bind(DoUnwrapKey, base::Passed(&state)))) {
[email protected]88be98562014-04-30 11:18:59733 CompleteWithThreadPoolError(&result);
734 }
[email protected]bd48e6412014-02-22 08:32:53735}
736
eroman1499b4942014-11-26 19:59:53737void WebCryptoImpl::deriveBits(const blink::WebCryptoAlgorithm& algorithm,
738 const blink::WebCryptoKey& base_key,
739 unsigned int length_bits,
740 blink::WebCryptoResult result) {
dcheng7036d1e52016-04-21 23:13:03741 std::unique_ptr<DeriveBitsState> state(
eroman1499b4942014-11-26 19:59:53742 new DeriveBitsState(algorithm, base_key, length_bits, result));
dcheng0917ec42015-11-19 07:00:20743 if (!CryptoThreadPool::PostTask(
744 FROM_HERE, base::Bind(DoDeriveBits, base::Passed(&state)))) {
eroman1499b4942014-11-26 19:59:53745 CompleteWithThreadPoolError(&result);
746 }
747}
748
eroman20bf4c3c2014-12-12 17:22:37749void WebCryptoImpl::deriveKey(
750 const blink::WebCryptoAlgorithm& algorithm,
751 const blink::WebCryptoKey& base_key,
752 const blink::WebCryptoAlgorithm& import_algorithm,
753 const blink::WebCryptoAlgorithm& key_length_algorithm,
754 bool extractable,
755 blink::WebCryptoKeyUsageMask usages,
756 blink::WebCryptoResult result) {
dcheng7036d1e52016-04-21 23:13:03757 std::unique_ptr<DeriveKeyState> state(
eroman20bf4c3c2014-12-12 17:22:37758 new DeriveKeyState(algorithm, base_key, import_algorithm,
759 key_length_algorithm, extractable, usages, result));
dcheng0917ec42015-11-19 07:00:20760 if (!CryptoThreadPool::PostTask(
761 FROM_HERE, base::Bind(DoDeriveKey, base::Passed(&state)))) {
eroman20bf4c3c2014-12-12 17:22:37762 CompleteWithThreadPoolError(&result);
763 }
764}
765
dcheng7578e8ee2016-07-13 03:52:45766std::unique_ptr<blink::WebCryptoDigestor> WebCryptoImpl::createDigestor(
[email protected]6f778f02014-04-01 02:31:33767 blink::WebCryptoAlgorithmId algorithm_id) {
dcheng7578e8ee2016-07-13 03:52:45768 return webcrypto::CreateDigestor(algorithm_id);
[email protected]6f778f02014-04-01 02:31:33769}
770
[email protected]5daca0472014-03-18 20:27:08771bool WebCryptoImpl::deserializeKeyForClone(
772 const blink::WebCryptoKeyAlgorithm& algorithm,
773 blink::WebCryptoKeyType type,
774 bool extractable,
775 blink::WebCryptoKeyUsageMask usages,
776 const unsigned char* key_data,
777 unsigned key_data_size,
778 blink::WebCryptoKey& key) {
[email protected]88be98562014-04-30 11:18:59779 return webcrypto::DeserializeKeyForClone(
eroman38bb4bd2014-11-24 23:47:06780 algorithm, type, extractable, usages,
781 webcrypto::CryptoData(key_data, key_data_size), &key);
[email protected]5daca0472014-03-18 20:27:08782}
783
784bool WebCryptoImpl::serializeKeyForClone(
785 const blink::WebCryptoKey& key,
786 blink::WebVector<unsigned char>& key_data) {
[email protected]88be98562014-04-30 11:18:59787 return webcrypto::SerializeKeyForClone(key, &key_data);
[email protected]5daca0472014-03-18 20:27:08788}
789
erg56f12322015-04-17 00:51:48790} // namespace webcrypto