blob: 205d5150ad982becfc504b04e2033cebb791f846 [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
[email protected]cf5d32e52014-03-07 18:00:085#include "content/child/webcrypto/webcrypto_impl.h"
[email protected]408699c2013-07-17 21:23:166
[email protected]88be98562014-04-30 11:18:597#include "base/bind.h"
8#include "base/lazy_instance.h"
9#include "base/location.h"
[email protected]c1b944a2013-10-23 06:33:2110#include "base/logging.h"
[email protected]6f778f02014-04-01 02:31:3311#include "base/memory/scoped_ptr.h"
[email protected]88be98562014-04-30 11:18:5912#include "base/single_thread_task_runner.h"
[email protected]4c1ae712014-07-23 17:48:0913#include "base/stl_util.h"
[email protected]88be98562014-04-30 11:18:5914#include "base/task_runner.h"
15#include "base/thread_task_runner_handle.h"
16#include "base/threading/sequenced_worker_pool.h"
17#include "base/threading/worker_pool.h"
[email protected]38409aec2014-07-19 00:54:5118#include "content/child/webcrypto/algorithm_dispatch.h"
[email protected]cf5d32e52014-03-07 18:00:0819#include "content/child/webcrypto/crypto_data.h"
eroman9b747eaf2014-10-18 22:03:2820#include "content/child/webcrypto/generate_key_result.h"
[email protected]37be4cfa2014-03-20 05:39:3721#include "content/child/webcrypto/status.h"
[email protected]38409aec2014-07-19 00:54:5122#include "content/child/webcrypto/structured_clone.h"
[email protected]cf5d32e52014-03-07 18:00:0823#include "content/child/webcrypto/webcrypto_util.h"
[email protected]88be98562014-04-30 11:18:5924#include "content/child/worker_thread_task_runner.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
28namespace content {
29
[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
39// take hundreds of milliseconds to several seconds.
40//
41// Moreover the underlying crypto libraries are not threadsafe when operating
42// on the same key.
43//
44// The strategy used here is to run a sequenced worker pool for all WebCrypto
45// operations. This pool (of 1 threads) is also used by requests started from
46// Blink Web Workers.
47//
48// A few notes to keep in mind:
49//
50// * PostTaskAndReply() cannot be used for two reasons:
51//
52// (1) Blink web worker threads do not have an associated message loop so
53// construction of the reply callback will crash.
54//
55// (2) PostTaskAndReply() handles failure posting the reply by leaking the
56// callback, rather than destroying it. In the case of Web Workers this
57// condition is reachable via normal execution, since Web Workers can
58// be stopped before the WebCrypto operation has finished. A policy of
59// leaking would therefore be problematic.
60//
61// * blink::WebArrayBuffer is NOT threadsafe, and should therefore be allocated
62// on the target Blink thread.
63//
64// TODO(eroman): Is there any way around this? Copying the result between
65// threads is silly.
66//
67// * WebCryptoAlgorithm and WebCryptoKey are threadsafe (however the key's
68// handle(), which wraps an NSS/OpenSSL type, may not be and should only be
69// used from the webcrypto thread).
70//
71// * blink::WebCryptoResult is not threadsafe and should only be operated on
72// the target Blink thread. HOWEVER, it is safe to delete it from any thread.
73// This can happen if by the time the operation has completed in the crypto
74// worker pool, the Blink worker thread that initiated the request is gone.
75// Posting back to the origin thread will fail, and the WebCryptoResult will
76// be deleted while running in the crypto worker pool.
77class CryptoThreadPool {
78 public:
79 CryptoThreadPool()
80 : worker_pool_(new base::SequencedWorkerPool(1, "WebCrypto")),
81 task_runner_(worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
82 worker_pool_->GetSequenceToken(),
83 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) {}
84
85 static bool PostTask(const tracked_objects::Location& from_here,
86 const base::Closure& task);
87
88 private:
89 scoped_refptr<base::SequencedWorkerPool> worker_pool_;
90 scoped_refptr<base::SequencedTaskRunner> task_runner_;
91};
92
93base::LazyInstance<CryptoThreadPool>::Leaky crypto_thread_pool =
94 LAZY_INSTANCE_INITIALIZER;
95
96bool CryptoThreadPool::PostTask(const tracked_objects::Location& from_here,
97 const base::Closure& task) {
98 return crypto_thread_pool.Get().task_runner_->PostTask(from_here, task);
99}
100
101void CompleteWithThreadPoolError(blink::WebCryptoResult* result) {
102 result->completeWithError(blink::WebCryptoErrorTypeOperation,
103 "Failed posting to crypto worker pool");
104}
105
[email protected]cca897482014-01-30 22:40:19106void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
107 DCHECK(status.IsError());
[email protected]c5039362014-04-28 19:10:34108
[email protected]c5039362014-04-28 19:10:34109 result->completeWithError(status.error_type(),
110 blink::WebString::fromUTF8(status.error_details()));
[email protected]cca897482014-01-30 22:40:19111}
112
[email protected]88be98562014-04-30 11:18:59113void CompleteWithBufferOrError(const Status& status,
[email protected]53b6c9d22014-07-19 05:08:38114 const std::vector<uint8_t>& buffer,
[email protected]88be98562014-04-30 11:18:59115 blink::WebCryptoResult* result) {
116 if (status.IsError()) {
117 CompleteWithError(status, result);
118 } else {
119 if (buffer.size() > UINT_MAX) {
120 // WebArrayBuffers have a smaller range than std::vector<>, so
121 // theoretically this could overflow.
122 CompleteWithError(Status::ErrorUnexpected(), result);
123 } else {
[email protected]4c1ae712014-07-23 17:48:09124 result->completeWithBuffer(vector_as_array(&buffer), buffer.size());
[email protected]88be98562014-04-30 11:18:59125 }
126 }
127}
128
129void CompleteWithKeyOrError(const Status& status,
130 const blink::WebCryptoKey& key,
131 blink::WebCryptoResult* result) {
132 if (status.IsError()) {
133 CompleteWithError(status, result);
134 } else {
135 result->completeWithKey(key);
136 }
137}
138
[email protected]88be98562014-04-30 11:18:59139// Gets a task runner for the current thread. The current thread is either:
140//
141// * The main Blink thread
142// * A Blink web worker thread
143//
144// A different mechanism is needed for posting to these threads. The main
145// thread has an associated message loop and can simply use
146// base::ThreadTaskRunnerHandle. Whereas the web worker threads are managed by
147// Blink and need to be indirected through WorkerThreadTaskRunner.
148scoped_refptr<base::TaskRunner> GetCurrentBlinkThread() {
149 if (base::ThreadTaskRunnerHandle::IsSet())
150 return base::ThreadTaskRunnerHandle::Get();
151 return WorkerThreadTaskRunner::current();
152}
153
154// --------------------------------------------------------------------
155// State
156// --------------------------------------------------------------------
157//
158// Explicit state classes are used rather than base::Bind(). This is done
159// both for clarity, but also to avoid extraneous allocations for things
160// like passing buffers and result objects between threads.
161//
162// BaseState is the base class common to all of the async operations, and
163// keeps track of the thread to complete on, the error state, and the
164// callback into Blink.
165//
166// Ownership of the State object is passed between the crypto thread and the
167// Blink thread. Under normal completion it is destroyed on the Blink thread.
168// However it may also be destroyed on the crypto thread if the Blink thread
169// has vanished (which can happen for Blink web worker threads).
170
171struct BaseState {
172 explicit BaseState(const blink::WebCryptoResult& result)
173 : origin_thread(GetCurrentBlinkThread()), result(result) {}
174
[email protected]345bd202014-06-19 04:51:16175 bool cancelled() {
[email protected]345bd202014-06-19 04:51:16176 return result.cancelled();
[email protected]345bd202014-06-19 04:51:16177 }
178
[email protected]88be98562014-04-30 11:18:59179 scoped_refptr<base::TaskRunner> origin_thread;
180
181 webcrypto::Status status;
182 blink::WebCryptoResult result;
183
184 protected:
185 // Since there is no virtual destructor, must not delete directly as a
186 // BaseState.
187 ~BaseState() {}
188};
189
190struct EncryptState : public BaseState {
191 EncryptState(const blink::WebCryptoAlgorithm& algorithm,
192 const blink::WebCryptoKey& key,
193 const unsigned char* data,
194 unsigned int data_size,
195 const blink::WebCryptoResult& result)
196 : BaseState(result),
197 algorithm(algorithm),
198 key(key),
199 data(data, data + data_size) {}
200
201 const blink::WebCryptoAlgorithm algorithm;
202 const blink::WebCryptoKey key;
[email protected]53b6c9d22014-07-19 05:08:38203 const std::vector<uint8_t> data;
[email protected]88be98562014-04-30 11:18:59204
[email protected]53b6c9d22014-07-19 05:08:38205 std::vector<uint8_t> buffer;
[email protected]88be98562014-04-30 11:18:59206};
207
208typedef EncryptState DecryptState;
209typedef EncryptState DigestState;
210
211struct GenerateKeyState : public BaseState {
212 GenerateKeyState(const blink::WebCryptoAlgorithm& algorithm,
213 bool extractable,
214 blink::WebCryptoKeyUsageMask usage_mask,
215 const blink::WebCryptoResult& result)
216 : BaseState(result),
217 algorithm(algorithm),
218 extractable(extractable),
eroman9b747eaf2014-10-18 22:03:28219 usage_mask(usage_mask) {}
[email protected]88be98562014-04-30 11:18:59220
221 const blink::WebCryptoAlgorithm algorithm;
222 const bool extractable;
223 const blink::WebCryptoKeyUsageMask usage_mask;
224
eroman9b747eaf2014-10-18 22:03:28225 webcrypto::GenerateKeyResult generate_key_result;
[email protected]88be98562014-04-30 11:18:59226};
227
228struct ImportKeyState : public BaseState {
229 ImportKeyState(blink::WebCryptoKeyFormat format,
230 const unsigned char* key_data,
231 unsigned int key_data_size,
232 const blink::WebCryptoAlgorithm& algorithm,
233 bool extractable,
234 blink::WebCryptoKeyUsageMask usage_mask,
235 const blink::WebCryptoResult& result)
236 : BaseState(result),
237 format(format),
238 key_data(key_data, key_data + key_data_size),
239 algorithm(algorithm),
240 extractable(extractable),
eroman7b9591ab2014-10-21 17:13:01241 usage_mask(usage_mask) {}
[email protected]88be98562014-04-30 11:18:59242
243 const blink::WebCryptoKeyFormat format;
[email protected]53b6c9d22014-07-19 05:08:38244 const std::vector<uint8_t> key_data;
[email protected]88be98562014-04-30 11:18:59245 const blink::WebCryptoAlgorithm algorithm;
246 const bool extractable;
247 const blink::WebCryptoKeyUsageMask usage_mask;
248
249 blink::WebCryptoKey key;
250};
251
252struct ExportKeyState : public BaseState {
253 ExportKeyState(blink::WebCryptoKeyFormat format,
254 const blink::WebCryptoKey& key,
255 const blink::WebCryptoResult& result)
256 : BaseState(result), format(format), key(key) {}
257
258 const blink::WebCryptoKeyFormat format;
259 const blink::WebCryptoKey key;
260
[email protected]53b6c9d22014-07-19 05:08:38261 std::vector<uint8_t> buffer;
[email protected]88be98562014-04-30 11:18:59262};
263
264typedef EncryptState SignState;
265
266struct VerifySignatureState : public BaseState {
267 VerifySignatureState(const blink::WebCryptoAlgorithm& algorithm,
268 const blink::WebCryptoKey& key,
269 const unsigned char* signature,
270 unsigned int signature_size,
271 const unsigned char* data,
272 unsigned int data_size,
273 const blink::WebCryptoResult& result)
274 : BaseState(result),
275 algorithm(algorithm),
276 key(key),
277 signature(signature, signature + signature_size),
278 data(data, data + data_size),
279 verify_result(false) {}
280
281 const blink::WebCryptoAlgorithm algorithm;
282 const blink::WebCryptoKey key;
[email protected]53b6c9d22014-07-19 05:08:38283 const std::vector<uint8_t> signature;
284 const std::vector<uint8_t> data;
[email protected]88be98562014-04-30 11:18:59285
286 bool verify_result;
287};
288
289struct WrapKeyState : public BaseState {
290 WrapKeyState(blink::WebCryptoKeyFormat format,
291 const blink::WebCryptoKey& key,
292 const blink::WebCryptoKey& wrapping_key,
293 const blink::WebCryptoAlgorithm& wrap_algorithm,
294 const blink::WebCryptoResult& result)
295 : BaseState(result),
296 format(format),
297 key(key),
298 wrapping_key(wrapping_key),
299 wrap_algorithm(wrap_algorithm) {}
300
301 const blink::WebCryptoKeyFormat format;
302 const blink::WebCryptoKey key;
303 const blink::WebCryptoKey wrapping_key;
304 const blink::WebCryptoAlgorithm wrap_algorithm;
305
[email protected]53b6c9d22014-07-19 05:08:38306 std::vector<uint8_t> buffer;
[email protected]88be98562014-04-30 11:18:59307};
308
309struct UnwrapKeyState : public BaseState {
310 UnwrapKeyState(blink::WebCryptoKeyFormat format,
311 const unsigned char* wrapped_key,
312 unsigned wrapped_key_size,
313 const blink::WebCryptoKey& wrapping_key,
314 const blink::WebCryptoAlgorithm& unwrap_algorithm,
315 const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
316 bool extractable,
317 blink::WebCryptoKeyUsageMask usages,
318 const blink::WebCryptoResult& result)
319 : BaseState(result),
320 format(format),
321 wrapped_key(wrapped_key, wrapped_key + wrapped_key_size),
322 wrapping_key(wrapping_key),
323 unwrap_algorithm(unwrap_algorithm),
324 unwrapped_key_algorithm(unwrapped_key_algorithm),
325 extractable(extractable),
eroman7b9591ab2014-10-21 17:13:01326 usages(usages) {}
[email protected]88be98562014-04-30 11:18:59327
328 const blink::WebCryptoKeyFormat format;
[email protected]53b6c9d22014-07-19 05:08:38329 const std::vector<uint8_t> wrapped_key;
[email protected]88be98562014-04-30 11:18:59330 const blink::WebCryptoKey wrapping_key;
331 const blink::WebCryptoAlgorithm unwrap_algorithm;
332 const blink::WebCryptoAlgorithm unwrapped_key_algorithm;
333 const bool extractable;
334 const blink::WebCryptoKeyUsageMask usages;
335
336 blink::WebCryptoKey unwrapped_key;
337};
338
339// --------------------------------------------------------------------
340// Wrapper functions
341// --------------------------------------------------------------------
342//
343// * The methods named Do*() run on the crypto thread.
344// * The methods named Do*Reply() run on the target Blink thread
345
346void DoEncryptReply(scoped_ptr<EncryptState> state) {
347 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
348}
349
350void DoEncrypt(scoped_ptr<EncryptState> passed_state) {
351 EncryptState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16352 if (state->cancelled())
353 return;
[email protected]88be98562014-04-30 11:18:59354 state->status = webcrypto::Encrypt(state->algorithm,
355 state->key,
356 webcrypto::CryptoData(state->data),
357 &state->buffer);
358 state->origin_thread->PostTask(
359 FROM_HERE, base::Bind(DoEncryptReply, Passed(&passed_state)));
360}
361
362void DoDecryptReply(scoped_ptr<DecryptState> state) {
363 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
364}
365
366void DoDecrypt(scoped_ptr<DecryptState> passed_state) {
367 DecryptState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16368 if (state->cancelled())
369 return;
[email protected]88be98562014-04-30 11:18:59370 state->status = webcrypto::Decrypt(state->algorithm,
371 state->key,
372 webcrypto::CryptoData(state->data),
373 &state->buffer);
374 state->origin_thread->PostTask(
375 FROM_HERE, base::Bind(DoDecryptReply, Passed(&passed_state)));
376}
377
378void DoDigestReply(scoped_ptr<DigestState> state) {
379 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
380}
381
382void DoDigest(scoped_ptr<DigestState> passed_state) {
383 DigestState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16384 if (state->cancelled())
385 return;
[email protected]88be98562014-04-30 11:18:59386 state->status = webcrypto::Digest(
387 state->algorithm, webcrypto::CryptoData(state->data), &state->buffer);
388 state->origin_thread->PostTask(
389 FROM_HERE, base::Bind(DoDigestReply, Passed(&passed_state)));
390}
391
392void DoGenerateKeyReply(scoped_ptr<GenerateKeyState> state) {
393 if (state->status.IsError()) {
394 CompleteWithError(state->status, &state->result);
395 } else {
eroman9b747eaf2014-10-18 22:03:28396 state->generate_key_result.Complete(&state->result);
[email protected]88be98562014-04-30 11:18:59397 }
398}
399
400void DoGenerateKey(scoped_ptr<GenerateKeyState> passed_state) {
401 GenerateKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16402 if (state->cancelled())
403 return;
eroman9b747eaf2014-10-18 22:03:28404 state->status = webcrypto::GenerateKey(state->algorithm,
405 state->extractable,
406 state->usage_mask,
407 &state->generate_key_result);
[email protected]88be98562014-04-30 11:18:59408 state->origin_thread->PostTask(
409 FROM_HERE, base::Bind(DoGenerateKeyReply, Passed(&passed_state)));
410}
411
412void DoImportKeyReply(scoped_ptr<ImportKeyState> state) {
413 CompleteWithKeyOrError(state->status, state->key, &state->result);
414}
415
416void DoImportKey(scoped_ptr<ImportKeyState> passed_state) {
417 ImportKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16418 if (state->cancelled())
419 return;
[email protected]88be98562014-04-30 11:18:59420 state->status = webcrypto::ImportKey(state->format,
421 webcrypto::CryptoData(state->key_data),
422 state->algorithm,
423 state->extractable,
424 state->usage_mask,
425 &state->key);
426 if (state->status.IsSuccess()) {
427 DCHECK(state->key.handle());
428 DCHECK(!state->key.algorithm().isNull());
429 DCHECK_EQ(state->extractable, state->key.extractable());
430 }
431
432 state->origin_thread->PostTask(
433 FROM_HERE, base::Bind(DoImportKeyReply, Passed(&passed_state)));
434}
435
436void DoExportKeyReply(scoped_ptr<ExportKeyState> state) {
[email protected]b7deaa082014-06-17 22:24:37437 if (state->format != blink::WebCryptoKeyFormatJwk) {
438 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
439 return;
440 }
441
442 if (state->status.IsError()) {
443 CompleteWithError(state->status, &state->result);
444 } else {
445 state->result.completeWithJson(
[email protected]4c1ae712014-07-23 17:48:09446 reinterpret_cast<const char*>(vector_as_array(&state->buffer)),
[email protected]b7deaa082014-06-17 22:24:37447 state->buffer.size());
448 }
[email protected]88be98562014-04-30 11:18:59449}
450
451void DoExportKey(scoped_ptr<ExportKeyState> passed_state) {
452 ExportKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16453 if (state->cancelled())
454 return;
[email protected]88be98562014-04-30 11:18:59455 state->status =
456 webcrypto::ExportKey(state->format, state->key, &state->buffer);
457 state->origin_thread->PostTask(
458 FROM_HERE, base::Bind(DoExportKeyReply, Passed(&passed_state)));
459}
460
461void DoSignReply(scoped_ptr<SignState> state) {
462 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
463}
464
465void DoSign(scoped_ptr<SignState> passed_state) {
466 SignState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16467 if (state->cancelled())
468 return;
[email protected]88be98562014-04-30 11:18:59469 state->status = webcrypto::Sign(state->algorithm,
470 state->key,
471 webcrypto::CryptoData(state->data),
472 &state->buffer);
473
474 state->origin_thread->PostTask(
475 FROM_HERE, base::Bind(DoSignReply, Passed(&passed_state)));
476}
477
478void DoVerifyReply(scoped_ptr<VerifySignatureState> state) {
479 if (state->status.IsError()) {
480 CompleteWithError(state->status, &state->result);
481 } else {
482 state->result.completeWithBoolean(state->verify_result);
483 }
484}
485
486void DoVerify(scoped_ptr<VerifySignatureState> passed_state) {
487 VerifySignatureState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16488 if (state->cancelled())
489 return;
[email protected]38409aec2014-07-19 00:54:51490 state->status = webcrypto::Verify(state->algorithm,
491 state->key,
492 webcrypto::CryptoData(state->signature),
493 webcrypto::CryptoData(state->data),
494 &state->verify_result);
[email protected]88be98562014-04-30 11:18:59495
496 state->origin_thread->PostTask(
497 FROM_HERE, base::Bind(DoVerifyReply, Passed(&passed_state)));
498}
499
500void DoWrapKeyReply(scoped_ptr<WrapKeyState> state) {
501 CompleteWithBufferOrError(state->status, state->buffer, &state->result);
502}
503
504void DoWrapKey(scoped_ptr<WrapKeyState> passed_state) {
505 WrapKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16506 if (state->cancelled())
507 return;
[email protected]88be98562014-04-30 11:18:59508 state->status = webcrypto::WrapKey(state->format,
[email protected]88be98562014-04-30 11:18:59509 state->key,
[email protected]82ca1532014-05-10 02:00:26510 state->wrapping_key,
[email protected]88be98562014-04-30 11:18:59511 state->wrap_algorithm,
512 &state->buffer);
513
514 state->origin_thread->PostTask(
515 FROM_HERE, base::Bind(DoWrapKeyReply, Passed(&passed_state)));
516}
517
518void DoUnwrapKeyReply(scoped_ptr<UnwrapKeyState> state) {
519 CompleteWithKeyOrError(state->status, state->unwrapped_key, &state->result);
520}
521
522void DoUnwrapKey(scoped_ptr<UnwrapKeyState> passed_state) {
523 UnwrapKeyState* state = passed_state.get();
[email protected]345bd202014-06-19 04:51:16524 if (state->cancelled())
525 return;
[email protected]88be98562014-04-30 11:18:59526 state->status =
527 webcrypto::UnwrapKey(state->format,
528 webcrypto::CryptoData(state->wrapped_key),
529 state->wrapping_key,
530 state->unwrap_algorithm,
531 state->unwrapped_key_algorithm,
532 state->extractable,
533 state->usages,
534 &state->unwrapped_key);
535
536 state->origin_thread->PostTask(
537 FROM_HERE, base::Bind(DoUnwrapKeyReply, Passed(&passed_state)));
538}
539
[email protected]043cf1d32013-11-02 13:27:30540} // namespace
541
[email protected]88be98562014-04-30 11:18:59542WebCryptoImpl::WebCryptoImpl() {
[email protected]88be98562014-04-30 11:18:59543}
[email protected]7e4c36f2013-09-12 06:10:19544
[email protected]88be98562014-04-30 11:18:59545WebCryptoImpl::~WebCryptoImpl() {
546}
[email protected]04166f82014-02-19 06:11:04547
[email protected]a60326552014-02-19 22:58:24548void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm& algorithm,
549 const blink::WebCryptoKey& key,
550 const unsigned char* data,
551 unsigned int data_size,
552 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34553 DCHECK(!algorithm.isNull());
[email protected]88be98562014-04-30 11:18:59554
555 scoped_ptr<EncryptState> state(
556 new EncryptState(algorithm, key, data, data_size, result));
557 if (!CryptoThreadPool::PostTask(FROM_HERE,
558 base::Bind(DoEncrypt, Passed(&state)))) {
559 CompleteWithThreadPoolError(&result);
560 }
[email protected]a2a06c732013-09-27 10:50:54561}
562
[email protected]a60326552014-02-19 22:58:24563void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm& algorithm,
564 const blink::WebCryptoKey& key,
565 const unsigned char* data,
566 unsigned int data_size,
567 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34568 DCHECK(!algorithm.isNull());
[email protected]88be98562014-04-30 11:18:59569
570 scoped_ptr<DecryptState> state(
571 new DecryptState(algorithm, key, data, data_size, result));
572 if (!CryptoThreadPool::PostTask(FROM_HERE,
573 base::Bind(DoDecrypt, Passed(&state)))) {
574 CompleteWithThreadPoolError(&result);
575 }
[email protected]868085a92013-10-01 00:42:30576}
577
[email protected]a60326552014-02-19 22:58:24578void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm,
579 const unsigned char* data,
580 unsigned int data_size,
581 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34582 DCHECK(!algorithm.isNull());
[email protected]88be98562014-04-30 11:18:59583
584 scoped_ptr<DigestState> state(new DigestState(
585 algorithm, blink::WebCryptoKey::createNull(), data, data_size, result));
586 if (!CryptoThreadPool::PostTask(FROM_HERE,
587 base::Bind(DoDigest, Passed(&state)))) {
588 CompleteWithThreadPoolError(&result);
589 }
[email protected]408699c2013-07-17 21:23:16590}
591
[email protected]a60326552014-02-19 22:58:24592void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm,
593 bool extractable,
594 blink::WebCryptoKeyUsageMask usage_mask,
595 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34596 DCHECK(!algorithm.isNull());
[email protected]88be98562014-04-30 11:18:59597
598 scoped_ptr<GenerateKeyState> state(
599 new GenerateKeyState(algorithm, extractable, usage_mask, result));
600 if (!CryptoThreadPool::PostTask(FROM_HERE,
601 base::Bind(DoGenerateKey, Passed(&state)))) {
602 CompleteWithThreadPoolError(&result);
[email protected]dfae8ab2013-10-10 19:45:06603 }
604}
605
[email protected]c7a94682014-03-20 22:58:40606void WebCryptoImpl::importKey(blink::WebCryptoKeyFormat format,
607 const unsigned char* key_data,
608 unsigned int key_data_size,
609 const blink::WebCryptoAlgorithm& algorithm,
610 bool extractable,
611 blink::WebCryptoKeyUsageMask usage_mask,
612 blink::WebCryptoResult result) {
[email protected]88be98562014-04-30 11:18:59613 scoped_ptr<ImportKeyState> state(new ImportKeyState(format,
614 key_data,
615 key_data_size,
616 algorithm,
617 extractable,
618 usage_mask,
619 result));
620 if (!CryptoThreadPool::PostTask(FROM_HERE,
621 base::Bind(DoImportKey, Passed(&state)))) {
622 CompleteWithThreadPoolError(&result);
[email protected]cca897482014-01-30 22:40:19623 }
[email protected]1c879bc92013-09-18 07:45:32624}
625
[email protected]a60326552014-02-19 22:58:24626void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format,
627 const blink::WebCryptoKey& key,
628 blink::WebCryptoResult result) {
[email protected]88be98562014-04-30 11:18:59629 scoped_ptr<ExportKeyState> state(new ExportKeyState(format, key, result));
630 if (!CryptoThreadPool::PostTask(FROM_HERE,
631 base::Bind(DoExportKey, Passed(&state)))) {
632 CompleteWithThreadPoolError(&result);
633 }
[email protected]e9b2c102013-11-26 04:26:33634}
635
[email protected]a60326552014-02-19 22:58:24636void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm& algorithm,
637 const blink::WebCryptoKey& key,
638 const unsigned char* data,
639 unsigned int data_size,
640 blink::WebCryptoResult result) {
[email protected]88be98562014-04-30 11:18:59641 scoped_ptr<SignState> state(
642 new SignState(algorithm, key, data, data_size, result));
643 if (!CryptoThreadPool::PostTask(FROM_HERE,
644 base::Bind(DoSign, Passed(&state)))) {
645 CompleteWithThreadPoolError(&result);
646 }
[email protected]1c879bc92013-09-18 07:45:32647}
648
[email protected]a60326552014-02-19 22:58:24649void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm& algorithm,
650 const blink::WebCryptoKey& key,
651 const unsigned char* signature,
652 unsigned int signature_size,
653 const unsigned char* data,
654 unsigned int data_size,
655 blink::WebCryptoResult result) {
[email protected]88be98562014-04-30 11:18:59656 scoped_ptr<VerifySignatureState> state(new VerifySignatureState(
657 algorithm, key, signature, signature_size, data, data_size, result));
658 if (!CryptoThreadPool::PostTask(FROM_HERE,
659 base::Bind(DoVerify, Passed(&state)))) {
660 CompleteWithThreadPoolError(&result);
661 }
[email protected]3ed00262013-09-26 22:28:10662}
663
[email protected]baa92842014-03-25 01:07:38664void WebCryptoImpl::wrapKey(blink::WebCryptoKeyFormat format,
665 const blink::WebCryptoKey& key,
666 const blink::WebCryptoKey& wrapping_key,
667 const blink::WebCryptoAlgorithm& wrap_algorithm,
668 blink::WebCryptoResult result) {
[email protected]88be98562014-04-30 11:18:59669 scoped_ptr<WrapKeyState> state(
670 new WrapKeyState(format, key, wrapping_key, wrap_algorithm, result));
671 if (!CryptoThreadPool::PostTask(FROM_HERE,
672 base::Bind(DoWrapKey, Passed(&state)))) {
673 CompleteWithThreadPoolError(&result);
674 }
[email protected]baa92842014-03-25 01:07:38675}
676
677void WebCryptoImpl::unwrapKey(
678 blink::WebCryptoKeyFormat format,
679 const unsigned char* wrapped_key,
680 unsigned wrapped_key_size,
681 const blink::WebCryptoKey& wrapping_key,
682 const blink::WebCryptoAlgorithm& unwrap_algorithm,
683 const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
684 bool extractable,
685 blink::WebCryptoKeyUsageMask usages,
686 blink::WebCryptoResult result) {
[email protected]88be98562014-04-30 11:18:59687 scoped_ptr<UnwrapKeyState> state(new UnwrapKeyState(format,
688 wrapped_key,
689 wrapped_key_size,
690 wrapping_key,
691 unwrap_algorithm,
692 unwrapped_key_algorithm,
693 extractable,
694 usages,
695 result));
696 if (!CryptoThreadPool::PostTask(FROM_HERE,
697 base::Bind(DoUnwrapKey, Passed(&state)))) {
698 CompleteWithThreadPoolError(&result);
699 }
[email protected]bd48e6412014-02-22 08:32:53700}
701
[email protected]6f778f02014-04-01 02:31:33702blink::WebCryptoDigestor* WebCryptoImpl::createDigestor(
703 blink::WebCryptoAlgorithmId algorithm_id) {
704 return webcrypto::CreateDigestor(algorithm_id).release();
705}
706
[email protected]5daca0472014-03-18 20:27:08707bool WebCryptoImpl::deserializeKeyForClone(
708 const blink::WebCryptoKeyAlgorithm& algorithm,
709 blink::WebCryptoKeyType type,
710 bool extractable,
711 blink::WebCryptoKeyUsageMask usages,
712 const unsigned char* key_data,
713 unsigned key_data_size,
714 blink::WebCryptoKey& key) {
[email protected]88be98562014-04-30 11:18:59715 // TODO(eroman): Rather than do the import immediately on the current thread,
716 // it could defer to the crypto thread.
717 return webcrypto::DeserializeKeyForClone(
[email protected]5daca0472014-03-18 20:27:08718 algorithm,
719 type,
720 extractable,
721 usages,
722 webcrypto::CryptoData(key_data, key_data_size),
723 &key);
[email protected]5daca0472014-03-18 20:27:08724}
725
726bool WebCryptoImpl::serializeKeyForClone(
727 const blink::WebCryptoKey& key,
728 blink::WebVector<unsigned char>& key_data) {
[email protected]88be98562014-04-30 11:18:59729 return webcrypto::SerializeKeyForClone(key, &key_data);
[email protected]5daca0472014-03-18 20:27:08730}
731
[email protected]408699c2013-07-17 21:23:16732} // namespace content