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 #include "content/child/webcrypto/webcrypto_impl.h"
8 #include "base/lazy_instance.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/stl_util.h"
14 #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"
18 #include "content/child/webcrypto/algorithm_dispatch.h"
19 #include "content/child/webcrypto/crypto_data.h"
20 #include "content/child/webcrypto/generate_key_result.h"
21 #include "content/child/webcrypto/status.h"
22 #include "content/child/webcrypto/webcrypto_util.h"
23 #include "content/child/worker_thread_task_runner.h"
24 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
25 #include "third_party/WebKit/public/platform/WebString.h"
29 using webcrypto::Status
;
33 // ---------------------
35 // ---------------------
37 // WebCrypto operations can be slow. For instance generating an RSA key can
40 // Moreover the underlying crypto libraries are not threadsafe when operating
43 // The strategy used here is to run a sequenced worker pool for all WebCrypto
44 // operations (except structured cloning). This same pool is also used by
45 // requests started from Blink Web Workers.
47 // A few notes to keep in mind:
49 // * PostTaskAndReply() cannot be used for two reasons:
51 // (1) Blink web worker threads do not have an associated message loop so
52 // construction of the reply callback will crash.
54 // (2) PostTaskAndReply() handles failure posting the reply by leaking the
55 // callback, rather than destroying it. In the case of Web Workers this
56 // condition is reachable via normal execution, since Web Workers can
57 // be stopped before the WebCrypto operation has finished. A policy of
58 // leaking would therefore be problematic.
60 // * blink::WebArrayBuffer is NOT threadsafe, and should therefore be allocated
61 // on the target Blink thread.
63 // TODO(eroman): Is there any way around this? Copying the result between
66 // * WebCryptoAlgorithm and WebCryptoKey are threadsafe (however the key's
67 // handle(), which wraps an NSS/OpenSSL type, may not be and should only be
68 // used from the webcrypto thread).
70 // * blink::WebCryptoResult is not threadsafe and should only be operated on
71 // the target Blink thread. HOWEVER, it is safe to delete it from any thread.
72 // This can happen if by the time the operation has completed in the crypto
73 // worker pool, the Blink worker thread that initiated the request is gone.
74 // Posting back to the origin thread will fail, and the WebCryptoResult will
75 // be deleted while running in the crypto worker pool.
76 class CryptoThreadPool
{
79 : worker_pool_(new base::SequencedWorkerPool(1, "WebCrypto")),
80 task_runner_(worker_pool_
->GetSequencedTaskRunnerWithShutdownBehavior(
81 worker_pool_
->GetSequenceToken(),
82 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
)) {}
84 static bool PostTask(const tracked_objects::Location
& from_here
,
85 const base::Closure
& task
);
88 scoped_refptr
<base::SequencedWorkerPool
> worker_pool_
;
89 scoped_refptr
<base::SequencedTaskRunner
> task_runner_
;
92 base::LazyInstance
<CryptoThreadPool
>::Leaky crypto_thread_pool
=
93 LAZY_INSTANCE_INITIALIZER
;
95 bool CryptoThreadPool::PostTask(const tracked_objects::Location
& from_here
,
96 const base::Closure
& task
) {
97 return crypto_thread_pool
.Get().task_runner_
->PostTask(from_here
, task
);
100 void CompleteWithThreadPoolError(blink::WebCryptoResult
* result
) {
101 result
->completeWithError(blink::WebCryptoErrorTypeOperation
,
102 "Failed posting to crypto worker pool");
105 void CompleteWithError(const Status
& status
, blink::WebCryptoResult
* result
) {
106 DCHECK(status
.IsError());
108 result
->completeWithError(status
.error_type(),
109 blink::WebString::fromUTF8(status
.error_details()));
112 void CompleteWithBufferOrError(const Status
& status
,
113 const std::vector
<uint8_t>& buffer
,
114 blink::WebCryptoResult
* result
) {
115 if (status
.IsError()) {
116 CompleteWithError(status
, result
);
118 if (buffer
.size() > UINT_MAX
) {
119 // WebArrayBuffers have a smaller range than std::vector<>, so
120 // theoretically this could overflow.
121 CompleteWithError(Status::ErrorUnexpected(), result
);
123 result
->completeWithBuffer(vector_as_array(&buffer
), buffer
.size());
128 void CompleteWithKeyOrError(const Status
& status
,
129 const blink::WebCryptoKey
& key
,
130 blink::WebCryptoResult
* result
) {
131 if (status
.IsError()) {
132 CompleteWithError(status
, result
);
134 result
->completeWithKey(key
);
138 // Gets a task runner for the current thread. The current thread is either:
140 // * The main Blink thread
141 // * A Blink web worker thread
143 // A different mechanism is needed for posting to these threads. The main
144 // thread has an associated message loop and can simply use
145 // base::ThreadTaskRunnerHandle. Whereas the web worker threads are managed by
146 // Blink and need to be indirected through WorkerThreadTaskRunner.
147 scoped_refptr
<base::TaskRunner
> GetCurrentBlinkThread() {
148 if (base::ThreadTaskRunnerHandle::IsSet())
149 return base::ThreadTaskRunnerHandle::Get();
150 return WorkerThreadTaskRunner::current();
153 // --------------------------------------------------------------------
155 // --------------------------------------------------------------------
157 // Explicit state classes are used rather than base::Bind(). This is done
158 // both for clarity, but also to avoid extraneous allocations for things
159 // like passing buffers and result objects between threads.
161 // BaseState is the base class common to all of the async operations, and
162 // keeps track of the thread to complete on, the error state, and the
163 // callback into Blink.
165 // Ownership of the State object is passed between the crypto thread and the
166 // Blink thread. Under normal completion it is destroyed on the Blink thread.
167 // However it may also be destroyed on the crypto thread if the Blink thread
168 // has vanished (which can happen for Blink web worker threads).
171 explicit BaseState(const blink::WebCryptoResult
& result
)
172 : origin_thread(GetCurrentBlinkThread()), result(result
) {}
174 bool cancelled() { return result
.cancelled(); }
176 scoped_refptr
<base::TaskRunner
> origin_thread
;
178 webcrypto::Status status
;
179 blink::WebCryptoResult result
;
182 // Since there is no virtual destructor, must not delete directly as a
187 struct EncryptState
: public BaseState
{
188 EncryptState(const blink::WebCryptoAlgorithm
& algorithm
,
189 const blink::WebCryptoKey
& key
,
190 const unsigned char* data
,
191 unsigned int data_size
,
192 const blink::WebCryptoResult
& result
)
194 algorithm(algorithm
),
196 data(data
, data
+ data_size
) {}
198 const blink::WebCryptoAlgorithm algorithm
;
199 const blink::WebCryptoKey key
;
200 const std::vector
<uint8_t> data
;
202 std::vector
<uint8_t> buffer
;
205 typedef EncryptState DecryptState
;
206 typedef EncryptState DigestState
;
208 struct GenerateKeyState
: public BaseState
{
209 GenerateKeyState(const blink::WebCryptoAlgorithm
& algorithm
,
211 blink::WebCryptoKeyUsageMask usages
,
212 const blink::WebCryptoResult
& result
)
214 algorithm(algorithm
),
215 extractable(extractable
),
218 const blink::WebCryptoAlgorithm algorithm
;
219 const bool extractable
;
220 const blink::WebCryptoKeyUsageMask usages
;
222 webcrypto::GenerateKeyResult generate_key_result
;
225 struct ImportKeyState
: public BaseState
{
226 ImportKeyState(blink::WebCryptoKeyFormat format
,
227 const unsigned char* key_data
,
228 unsigned int key_data_size
,
229 const blink::WebCryptoAlgorithm
& algorithm
,
231 blink::WebCryptoKeyUsageMask usages
,
232 const blink::WebCryptoResult
& result
)
235 key_data(key_data
, key_data
+ key_data_size
),
236 algorithm(algorithm
),
237 extractable(extractable
),
240 const blink::WebCryptoKeyFormat format
;
241 const std::vector
<uint8_t> key_data
;
242 const blink::WebCryptoAlgorithm algorithm
;
243 const bool extractable
;
244 const blink::WebCryptoKeyUsageMask usages
;
246 blink::WebCryptoKey key
;
249 struct ExportKeyState
: public BaseState
{
250 ExportKeyState(blink::WebCryptoKeyFormat format
,
251 const blink::WebCryptoKey
& key
,
252 const blink::WebCryptoResult
& result
)
253 : BaseState(result
), format(format
), key(key
) {}
255 const blink::WebCryptoKeyFormat format
;
256 const blink::WebCryptoKey key
;
258 std::vector
<uint8_t> buffer
;
261 typedef EncryptState SignState
;
263 struct VerifySignatureState
: public BaseState
{
264 VerifySignatureState(const blink::WebCryptoAlgorithm
& algorithm
,
265 const blink::WebCryptoKey
& key
,
266 const unsigned char* signature
,
267 unsigned int signature_size
,
268 const unsigned char* data
,
269 unsigned int data_size
,
270 const blink::WebCryptoResult
& result
)
272 algorithm(algorithm
),
274 signature(signature
, signature
+ signature_size
),
275 data(data
, data
+ data_size
),
276 verify_result(false) {}
278 const blink::WebCryptoAlgorithm algorithm
;
279 const blink::WebCryptoKey key
;
280 const std::vector
<uint8_t> signature
;
281 const std::vector
<uint8_t> data
;
286 struct WrapKeyState
: public BaseState
{
287 WrapKeyState(blink::WebCryptoKeyFormat format
,
288 const blink::WebCryptoKey
& key
,
289 const blink::WebCryptoKey
& wrapping_key
,
290 const blink::WebCryptoAlgorithm
& wrap_algorithm
,
291 const blink::WebCryptoResult
& result
)
295 wrapping_key(wrapping_key
),
296 wrap_algorithm(wrap_algorithm
) {}
298 const blink::WebCryptoKeyFormat format
;
299 const blink::WebCryptoKey key
;
300 const blink::WebCryptoKey wrapping_key
;
301 const blink::WebCryptoAlgorithm wrap_algorithm
;
303 std::vector
<uint8_t> buffer
;
306 struct UnwrapKeyState
: public BaseState
{
307 UnwrapKeyState(blink::WebCryptoKeyFormat format
,
308 const unsigned char* wrapped_key
,
309 unsigned wrapped_key_size
,
310 const blink::WebCryptoKey
& wrapping_key
,
311 const blink::WebCryptoAlgorithm
& unwrap_algorithm
,
312 const blink::WebCryptoAlgorithm
& unwrapped_key_algorithm
,
314 blink::WebCryptoKeyUsageMask usages
,
315 const blink::WebCryptoResult
& result
)
318 wrapped_key(wrapped_key
, wrapped_key
+ wrapped_key_size
),
319 wrapping_key(wrapping_key
),
320 unwrap_algorithm(unwrap_algorithm
),
321 unwrapped_key_algorithm(unwrapped_key_algorithm
),
322 extractable(extractable
),
325 const blink::WebCryptoKeyFormat format
;
326 const std::vector
<uint8_t> wrapped_key
;
327 const blink::WebCryptoKey wrapping_key
;
328 const blink::WebCryptoAlgorithm unwrap_algorithm
;
329 const blink::WebCryptoAlgorithm unwrapped_key_algorithm
;
330 const bool extractable
;
331 const blink::WebCryptoKeyUsageMask usages
;
333 blink::WebCryptoKey unwrapped_key
;
336 struct DeriveBitsState
: public BaseState
{
337 DeriveBitsState(const blink::WebCryptoAlgorithm
& algorithm
,
338 const blink::WebCryptoKey
& base_key
,
339 unsigned int length_bits
,
340 const blink::WebCryptoResult
& result
)
342 algorithm(algorithm
),
344 length_bits(length_bits
) {}
346 const blink::WebCryptoAlgorithm algorithm
;
347 const blink::WebCryptoKey base_key
;
348 const unsigned int length_bits
;
350 std::vector
<uint8_t> derived_bytes
;
353 struct DeriveKeyState
: public BaseState
{
354 DeriveKeyState(const blink::WebCryptoAlgorithm
& algorithm
,
355 const blink::WebCryptoKey
& base_key
,
356 const blink::WebCryptoAlgorithm
& import_algorithm
,
357 const blink::WebCryptoAlgorithm
& key_length_algorithm
,
359 blink::WebCryptoKeyUsageMask usages
,
360 const blink::WebCryptoResult
& result
)
362 algorithm(algorithm
),
364 import_algorithm(import_algorithm
),
365 key_length_algorithm(key_length_algorithm
),
366 extractable(extractable
),
369 const blink::WebCryptoAlgorithm algorithm
;
370 const blink::WebCryptoKey base_key
;
371 const blink::WebCryptoAlgorithm import_algorithm
;
372 const blink::WebCryptoAlgorithm key_length_algorithm
;
374 blink::WebCryptoKeyUsageMask usages
;
376 blink::WebCryptoKey derived_key
;
379 // --------------------------------------------------------------------
381 // --------------------------------------------------------------------
383 // * The methods named Do*() run on the crypto thread.
384 // * The methods named Do*Reply() run on the target Blink thread
386 void DoEncryptReply(scoped_ptr
<EncryptState
> state
) {
387 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
390 void DoEncrypt(scoped_ptr
<EncryptState
> passed_state
) {
391 EncryptState
* state
= passed_state
.get();
392 if (state
->cancelled())
395 webcrypto::Encrypt(state
->algorithm
, state
->key
,
396 webcrypto::CryptoData(state
->data
), &state
->buffer
);
397 state
->origin_thread
->PostTask(
398 FROM_HERE
, base::Bind(DoEncryptReply
, Passed(&passed_state
)));
401 void DoDecryptReply(scoped_ptr
<DecryptState
> state
) {
402 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
405 void DoDecrypt(scoped_ptr
<DecryptState
> passed_state
) {
406 DecryptState
* state
= passed_state
.get();
407 if (state
->cancelled())
410 webcrypto::Decrypt(state
->algorithm
, state
->key
,
411 webcrypto::CryptoData(state
->data
), &state
->buffer
);
412 state
->origin_thread
->PostTask(
413 FROM_HERE
, base::Bind(DoDecryptReply
, Passed(&passed_state
)));
416 void DoDigestReply(scoped_ptr
<DigestState
> state
) {
417 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
420 void DoDigest(scoped_ptr
<DigestState
> passed_state
) {
421 DigestState
* state
= passed_state
.get();
422 if (state
->cancelled())
424 state
->status
= webcrypto::Digest(
425 state
->algorithm
, webcrypto::CryptoData(state
->data
), &state
->buffer
);
426 state
->origin_thread
->PostTask(
427 FROM_HERE
, base::Bind(DoDigestReply
, Passed(&passed_state
)));
430 void DoGenerateKeyReply(scoped_ptr
<GenerateKeyState
> state
) {
431 if (state
->status
.IsError()) {
432 CompleteWithError(state
->status
, &state
->result
);
434 state
->generate_key_result
.Complete(&state
->result
);
438 void DoGenerateKey(scoped_ptr
<GenerateKeyState
> passed_state
) {
439 GenerateKeyState
* state
= passed_state
.get();
440 if (state
->cancelled())
443 webcrypto::GenerateKey(state
->algorithm
, state
->extractable
,
444 state
->usages
, &state
->generate_key_result
);
445 state
->origin_thread
->PostTask(
446 FROM_HERE
, base::Bind(DoGenerateKeyReply
, Passed(&passed_state
)));
449 void DoImportKeyReply(scoped_ptr
<ImportKeyState
> state
) {
450 CompleteWithKeyOrError(state
->status
, state
->key
, &state
->result
);
453 void DoImportKey(scoped_ptr
<ImportKeyState
> passed_state
) {
454 ImportKeyState
* state
= passed_state
.get();
455 if (state
->cancelled())
457 state
->status
= webcrypto::ImportKey(
458 state
->format
, webcrypto::CryptoData(state
->key_data
), state
->algorithm
,
459 state
->extractable
, state
->usages
, &state
->key
);
460 if (state
->status
.IsSuccess()) {
461 DCHECK(state
->key
.handle());
462 DCHECK(!state
->key
.algorithm().isNull());
463 DCHECK_EQ(state
->extractable
, state
->key
.extractable());
466 state
->origin_thread
->PostTask(
467 FROM_HERE
, base::Bind(DoImportKeyReply
, Passed(&passed_state
)));
470 void DoExportKeyReply(scoped_ptr
<ExportKeyState
> state
) {
471 if (state
->format
!= blink::WebCryptoKeyFormatJwk
) {
472 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
476 if (state
->status
.IsError()) {
477 CompleteWithError(state
->status
, &state
->result
);
479 state
->result
.completeWithJson(
480 reinterpret_cast<const char*>(vector_as_array(&state
->buffer
)),
481 state
->buffer
.size());
485 void DoExportKey(scoped_ptr
<ExportKeyState
> passed_state
) {
486 ExportKeyState
* state
= passed_state
.get();
487 if (state
->cancelled())
490 webcrypto::ExportKey(state
->format
, state
->key
, &state
->buffer
);
491 state
->origin_thread
->PostTask(
492 FROM_HERE
, base::Bind(DoExportKeyReply
, Passed(&passed_state
)));
495 void DoSignReply(scoped_ptr
<SignState
> state
) {
496 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
499 void DoSign(scoped_ptr
<SignState
> passed_state
) {
500 SignState
* state
= passed_state
.get();
501 if (state
->cancelled())
504 webcrypto::Sign(state
->algorithm
, state
->key
,
505 webcrypto::CryptoData(state
->data
), &state
->buffer
);
507 state
->origin_thread
->PostTask(
508 FROM_HERE
, base::Bind(DoSignReply
, Passed(&passed_state
)));
511 void DoVerifyReply(scoped_ptr
<VerifySignatureState
> state
) {
512 if (state
->status
.IsError()) {
513 CompleteWithError(state
->status
, &state
->result
);
515 state
->result
.completeWithBoolean(state
->verify_result
);
519 void DoVerify(scoped_ptr
<VerifySignatureState
> passed_state
) {
520 VerifySignatureState
* state
= passed_state
.get();
521 if (state
->cancelled())
523 state
->status
= webcrypto::Verify(
524 state
->algorithm
, state
->key
, webcrypto::CryptoData(state
->signature
),
525 webcrypto::CryptoData(state
->data
), &state
->verify_result
);
527 state
->origin_thread
->PostTask(
528 FROM_HERE
, base::Bind(DoVerifyReply
, Passed(&passed_state
)));
531 void DoWrapKeyReply(scoped_ptr
<WrapKeyState
> state
) {
532 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
535 void DoWrapKey(scoped_ptr
<WrapKeyState
> passed_state
) {
536 WrapKeyState
* state
= passed_state
.get();
537 if (state
->cancelled())
540 webcrypto::WrapKey(state
->format
, state
->key
, state
->wrapping_key
,
541 state
->wrap_algorithm
, &state
->buffer
);
543 state
->origin_thread
->PostTask(
544 FROM_HERE
, base::Bind(DoWrapKeyReply
, Passed(&passed_state
)));
547 void DoUnwrapKeyReply(scoped_ptr
<UnwrapKeyState
> state
) {
548 CompleteWithKeyOrError(state
->status
, state
->unwrapped_key
, &state
->result
);
551 void DoUnwrapKey(scoped_ptr
<UnwrapKeyState
> passed_state
) {
552 UnwrapKeyState
* state
= passed_state
.get();
553 if (state
->cancelled())
555 state
->status
= webcrypto::UnwrapKey(
556 state
->format
, webcrypto::CryptoData(state
->wrapped_key
),
557 state
->wrapping_key
, state
->unwrap_algorithm
,
558 state
->unwrapped_key_algorithm
, state
->extractable
, state
->usages
,
559 &state
->unwrapped_key
);
561 state
->origin_thread
->PostTask(
562 FROM_HERE
, base::Bind(DoUnwrapKeyReply
, Passed(&passed_state
)));
565 void DoDeriveBitsReply(scoped_ptr
<DeriveBitsState
> state
) {
566 CompleteWithBufferOrError(state
->status
, state
->derived_bytes
,
570 void DoDeriveBits(scoped_ptr
<DeriveBitsState
> passed_state
) {
571 DeriveBitsState
* state
= passed_state
.get();
572 if (state
->cancelled())
575 webcrypto::DeriveBits(state
->algorithm
, state
->base_key
,
576 state
->length_bits
, &state
->derived_bytes
);
577 state
->origin_thread
->PostTask(
578 FROM_HERE
, base::Bind(DoDeriveBitsReply
, Passed(&passed_state
)));
581 void DoDeriveKeyReply(scoped_ptr
<DeriveKeyState
> state
) {
582 CompleteWithKeyOrError(state
->status
, state
->derived_key
, &state
->result
);
585 void DoDeriveKey(scoped_ptr
<DeriveKeyState
> passed_state
) {
586 DeriveKeyState
* state
= passed_state
.get();
587 if (state
->cancelled())
589 state
->status
= webcrypto::DeriveKey(
590 state
->algorithm
, state
->base_key
, state
->import_algorithm
,
591 state
->key_length_algorithm
, state
->extractable
, state
->usages
,
592 &state
->derived_key
);
593 state
->origin_thread
->PostTask(
594 FROM_HERE
, base::Bind(DoDeriveKeyReply
, Passed(&passed_state
)));
599 WebCryptoImpl::WebCryptoImpl() {
602 WebCryptoImpl::~WebCryptoImpl() {
605 void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm
& algorithm
,
606 const blink::WebCryptoKey
& key
,
607 const unsigned char* data
,
608 unsigned int data_size
,
609 blink::WebCryptoResult result
) {
610 DCHECK(!algorithm
.isNull());
612 scoped_ptr
<EncryptState
> state(
613 new EncryptState(algorithm
, key
, data
, data_size
, result
));
614 if (!CryptoThreadPool::PostTask(FROM_HERE
,
615 base::Bind(DoEncrypt
, Passed(&state
)))) {
616 CompleteWithThreadPoolError(&result
);
620 void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm
& algorithm
,
621 const blink::WebCryptoKey
& key
,
622 const unsigned char* data
,
623 unsigned int data_size
,
624 blink::WebCryptoResult result
) {
625 DCHECK(!algorithm
.isNull());
627 scoped_ptr
<DecryptState
> state(
628 new DecryptState(algorithm
, key
, data
, data_size
, result
));
629 if (!CryptoThreadPool::PostTask(FROM_HERE
,
630 base::Bind(DoDecrypt
, Passed(&state
)))) {
631 CompleteWithThreadPoolError(&result
);
635 void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm
& algorithm
,
636 const unsigned char* data
,
637 unsigned int data_size
,
638 blink::WebCryptoResult result
) {
639 DCHECK(!algorithm
.isNull());
641 scoped_ptr
<DigestState
> state(new DigestState(
642 algorithm
, blink::WebCryptoKey::createNull(), data
, data_size
, result
));
643 if (!CryptoThreadPool::PostTask(FROM_HERE
,
644 base::Bind(DoDigest
, Passed(&state
)))) {
645 CompleteWithThreadPoolError(&result
);
649 void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm
& algorithm
,
651 blink::WebCryptoKeyUsageMask usages
,
652 blink::WebCryptoResult result
) {
653 DCHECK(!algorithm
.isNull());
655 scoped_ptr
<GenerateKeyState
> state(
656 new GenerateKeyState(algorithm
, extractable
, usages
, result
));
657 if (!CryptoThreadPool::PostTask(FROM_HERE
,
658 base::Bind(DoGenerateKey
, Passed(&state
)))) {
659 CompleteWithThreadPoolError(&result
);
663 void WebCryptoImpl::importKey(blink::WebCryptoKeyFormat format
,
664 const unsigned char* key_data
,
665 unsigned int key_data_size
,
666 const blink::WebCryptoAlgorithm
& algorithm
,
668 blink::WebCryptoKeyUsageMask usages
,
669 blink::WebCryptoResult result
) {
670 scoped_ptr
<ImportKeyState
> state(new ImportKeyState(
671 format
, key_data
, key_data_size
, algorithm
, extractable
, usages
, result
));
672 if (!CryptoThreadPool::PostTask(FROM_HERE
,
673 base::Bind(DoImportKey
, Passed(&state
)))) {
674 CompleteWithThreadPoolError(&result
);
678 void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format
,
679 const blink::WebCryptoKey
& key
,
680 blink::WebCryptoResult result
) {
681 scoped_ptr
<ExportKeyState
> state(new ExportKeyState(format
, key
, result
));
682 if (!CryptoThreadPool::PostTask(FROM_HERE
,
683 base::Bind(DoExportKey
, Passed(&state
)))) {
684 CompleteWithThreadPoolError(&result
);
688 void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm
& algorithm
,
689 const blink::WebCryptoKey
& key
,
690 const unsigned char* data
,
691 unsigned int data_size
,
692 blink::WebCryptoResult result
) {
693 scoped_ptr
<SignState
> state(
694 new SignState(algorithm
, key
, data
, data_size
, result
));
695 if (!CryptoThreadPool::PostTask(FROM_HERE
,
696 base::Bind(DoSign
, Passed(&state
)))) {
697 CompleteWithThreadPoolError(&result
);
701 void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm
& algorithm
,
702 const blink::WebCryptoKey
& key
,
703 const unsigned char* signature
,
704 unsigned int signature_size
,
705 const unsigned char* data
,
706 unsigned int data_size
,
707 blink::WebCryptoResult result
) {
708 scoped_ptr
<VerifySignatureState
> state(new VerifySignatureState(
709 algorithm
, key
, signature
, signature_size
, data
, data_size
, result
));
710 if (!CryptoThreadPool::PostTask(FROM_HERE
,
711 base::Bind(DoVerify
, Passed(&state
)))) {
712 CompleteWithThreadPoolError(&result
);
716 void WebCryptoImpl::wrapKey(blink::WebCryptoKeyFormat format
,
717 const blink::WebCryptoKey
& key
,
718 const blink::WebCryptoKey
& wrapping_key
,
719 const blink::WebCryptoAlgorithm
& wrap_algorithm
,
720 blink::WebCryptoResult result
) {
721 scoped_ptr
<WrapKeyState
> state(
722 new WrapKeyState(format
, key
, wrapping_key
, wrap_algorithm
, result
));
723 if (!CryptoThreadPool::PostTask(FROM_HERE
,
724 base::Bind(DoWrapKey
, Passed(&state
)))) {
725 CompleteWithThreadPoolError(&result
);
729 void WebCryptoImpl::unwrapKey(
730 blink::WebCryptoKeyFormat format
,
731 const unsigned char* wrapped_key
,
732 unsigned wrapped_key_size
,
733 const blink::WebCryptoKey
& wrapping_key
,
734 const blink::WebCryptoAlgorithm
& unwrap_algorithm
,
735 const blink::WebCryptoAlgorithm
& unwrapped_key_algorithm
,
737 blink::WebCryptoKeyUsageMask usages
,
738 blink::WebCryptoResult result
) {
739 scoped_ptr
<UnwrapKeyState
> state(new UnwrapKeyState(
740 format
, wrapped_key
, wrapped_key_size
, wrapping_key
, unwrap_algorithm
,
741 unwrapped_key_algorithm
, extractable
, usages
, result
));
742 if (!CryptoThreadPool::PostTask(FROM_HERE
,
743 base::Bind(DoUnwrapKey
, Passed(&state
)))) {
744 CompleteWithThreadPoolError(&result
);
748 void WebCryptoImpl::deriveBits(const blink::WebCryptoAlgorithm
& algorithm
,
749 const blink::WebCryptoKey
& base_key
,
750 unsigned int length_bits
,
751 blink::WebCryptoResult result
) {
752 scoped_ptr
<DeriveBitsState
> state(
753 new DeriveBitsState(algorithm
, base_key
, length_bits
, result
));
754 if (!CryptoThreadPool::PostTask(FROM_HERE
,
755 base::Bind(DoDeriveBits
, Passed(&state
)))) {
756 CompleteWithThreadPoolError(&result
);
760 void WebCryptoImpl::deriveKey(
761 const blink::WebCryptoAlgorithm
& algorithm
,
762 const blink::WebCryptoKey
& base_key
,
763 const blink::WebCryptoAlgorithm
& import_algorithm
,
764 const blink::WebCryptoAlgorithm
& key_length_algorithm
,
766 blink::WebCryptoKeyUsageMask usages
,
767 blink::WebCryptoResult result
) {
768 scoped_ptr
<DeriveKeyState
> state(
769 new DeriveKeyState(algorithm
, base_key
, import_algorithm
,
770 key_length_algorithm
, extractable
, usages
, result
));
771 if (!CryptoThreadPool::PostTask(FROM_HERE
,
772 base::Bind(DoDeriveKey
, Passed(&state
)))) {
773 CompleteWithThreadPoolError(&result
);
777 blink::WebCryptoDigestor
* WebCryptoImpl::createDigestor(
778 blink::WebCryptoAlgorithmId algorithm_id
) {
779 return webcrypto::CreateDigestor(algorithm_id
).release();
782 bool WebCryptoImpl::deserializeKeyForClone(
783 const blink::WebCryptoKeyAlgorithm
& algorithm
,
784 blink::WebCryptoKeyType type
,
786 blink::WebCryptoKeyUsageMask usages
,
787 const unsigned char* key_data
,
788 unsigned key_data_size
,
789 blink::WebCryptoKey
& key
) {
790 return webcrypto::DeserializeKeyForClone(
791 algorithm
, type
, extractable
, usages
,
792 webcrypto::CryptoData(key_data
, key_data_size
), &key
);
795 bool WebCryptoImpl::serializeKeyForClone(
796 const blink::WebCryptoKey
& key
,
797 blink::WebVector
<unsigned char>& key_data
) {
798 return webcrypto::SerializeKeyForClone(key
, &key_data
);
801 } // namespace content