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 "components/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 "components/webcrypto/algorithm_dispatch.h"
19 #include "components/webcrypto/crypto_data.h"
20 #include "components/webcrypto/generate_key_result.h"
21 #include "components/webcrypto/status.h"
22 #include "components/webcrypto/webcrypto_util.h"
23 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
24 #include "third_party/WebKit/public/platform/WebString.h"
28 using webcrypto::Status
;
32 // ---------------------
34 // ---------------------
36 // WebCrypto operations can be slow. For instance generating an RSA key can
39 // Moreover the underlying crypto libraries are not threadsafe when operating
42 // The strategy used here is to run a sequenced worker pool for all WebCrypto
43 // operations (except structured cloning). This same pool is also used by
44 // requests started from Blink Web Workers.
46 // A few notes to keep in mind:
48 // * PostTaskAndReply() cannot be used for two reasons:
50 // (1) Blink web worker threads do not have an associated message loop so
51 // construction of the reply callback will crash.
53 // (2) PostTaskAndReply() handles failure posting the reply by leaking the
54 // callback, rather than destroying it. In the case of Web Workers this
55 // condition is reachable via normal execution, since Web Workers can
56 // be stopped before the WebCrypto operation has finished. A policy of
57 // leaking would therefore be problematic.
59 // * blink::WebArrayBuffer is NOT threadsafe, and should therefore be allocated
60 // on the target Blink thread.
62 // TODO(eroman): Is there any way around this? Copying the result between
65 // * WebCryptoAlgorithm and WebCryptoKey are threadsafe (however the key's
66 // handle(), which wraps an OpenSSL type, may not be and should only be
67 // used from the webcrypto thread).
69 // * blink::WebCryptoResult is not threadsafe and should only be operated on
70 // the target Blink thread. HOWEVER, it is safe to delete it from any thread.
71 // This can happen if by the time the operation has completed in the crypto
72 // worker pool, the Blink worker thread that initiated the request is gone.
73 // Posting back to the origin thread will fail, and the WebCryptoResult will
74 // be deleted while running in the crypto worker pool.
75 class CryptoThreadPool
{
78 : worker_pool_(new base::SequencedWorkerPool(1, "WebCrypto")),
79 task_runner_(worker_pool_
->GetSequencedTaskRunnerWithShutdownBehavior(
80 worker_pool_
->GetSequenceToken(),
81 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
)) {}
83 static bool PostTask(const tracked_objects::Location
& from_here
,
84 const base::Closure
& task
);
87 scoped_refptr
<base::SequencedWorkerPool
> worker_pool_
;
88 scoped_refptr
<base::SequencedTaskRunner
> task_runner_
;
91 base::LazyInstance
<CryptoThreadPool
>::Leaky crypto_thread_pool
=
92 LAZY_INSTANCE_INITIALIZER
;
94 bool CryptoThreadPool::PostTask(const tracked_objects::Location
& from_here
,
95 const base::Closure
& task
) {
96 return crypto_thread_pool
.Get().task_runner_
->PostTask(from_here
, task
);
99 void CompleteWithThreadPoolError(blink::WebCryptoResult
* result
) {
100 result
->completeWithError(blink::WebCryptoErrorTypeOperation
,
101 "Failed posting to crypto worker pool");
104 void CompleteWithError(const Status
& status
, blink::WebCryptoResult
* result
) {
105 DCHECK(status
.IsError());
107 result
->completeWithError(status
.error_type(),
108 blink::WebString::fromUTF8(status
.error_details()));
111 void CompleteWithBufferOrError(const Status
& status
,
112 const std::vector
<uint8_t>& buffer
,
113 blink::WebCryptoResult
* result
) {
114 if (status
.IsError()) {
115 CompleteWithError(status
, result
);
117 if (buffer
.size() > UINT_MAX
) {
118 // WebArrayBuffers have a smaller range than std::vector<>, so
119 // theoretically this could overflow.
120 CompleteWithError(Status::ErrorUnexpected(), result
);
122 result
->completeWithBuffer(vector_as_array(&buffer
),
123 static_cast<unsigned int>(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.
139 scoped_refptr
<base::TaskRunner
> GetCurrentBlinkThread() {
140 DCHECK(base::ThreadTaskRunnerHandle::IsSet());
141 return base::ThreadTaskRunnerHandle::Get();
144 // --------------------------------------------------------------------
146 // --------------------------------------------------------------------
148 // Explicit state classes are used rather than base::Bind(). This is done
149 // both for clarity, but also to avoid extraneous allocations for things
150 // like passing buffers and result objects between threads.
152 // BaseState is the base class common to all of the async operations, and
153 // keeps track of the thread to complete on, the error state, and the
154 // callback into Blink.
156 // Ownership of the State object is passed between the crypto thread and the
157 // Blink thread. Under normal completion it is destroyed on the Blink thread.
158 // However it may also be destroyed on the crypto thread if the Blink thread
159 // has vanished (which can happen for Blink web worker threads).
162 explicit BaseState(const blink::WebCryptoResult
& result
)
163 : origin_thread(GetCurrentBlinkThread()), result(result
) {}
165 bool cancelled() { return result
.cancelled(); }
167 scoped_refptr
<base::TaskRunner
> origin_thread
;
169 webcrypto::Status status
;
170 blink::WebCryptoResult result
;
173 // Since there is no virtual destructor, must not delete directly as a
178 struct EncryptState
: public BaseState
{
179 EncryptState(const blink::WebCryptoAlgorithm
& algorithm
,
180 const blink::WebCryptoKey
& key
,
181 const unsigned char* data
,
182 unsigned int data_size
,
183 const blink::WebCryptoResult
& result
)
185 algorithm(algorithm
),
187 data(data
, data
+ data_size
) {}
189 const blink::WebCryptoAlgorithm algorithm
;
190 const blink::WebCryptoKey key
;
191 const std::vector
<uint8_t> data
;
193 std::vector
<uint8_t> buffer
;
196 typedef EncryptState DecryptState
;
197 typedef EncryptState DigestState
;
199 struct GenerateKeyState
: public BaseState
{
200 GenerateKeyState(const blink::WebCryptoAlgorithm
& algorithm
,
202 blink::WebCryptoKeyUsageMask usages
,
203 const blink::WebCryptoResult
& result
)
205 algorithm(algorithm
),
206 extractable(extractable
),
209 const blink::WebCryptoAlgorithm algorithm
;
210 const bool extractable
;
211 const blink::WebCryptoKeyUsageMask usages
;
213 webcrypto::GenerateKeyResult generate_key_result
;
216 struct ImportKeyState
: public BaseState
{
217 ImportKeyState(blink::WebCryptoKeyFormat format
,
218 const unsigned char* key_data
,
219 unsigned int key_data_size
,
220 const blink::WebCryptoAlgorithm
& algorithm
,
222 blink::WebCryptoKeyUsageMask usages
,
223 const blink::WebCryptoResult
& result
)
226 key_data(key_data
, key_data
+ key_data_size
),
227 algorithm(algorithm
),
228 extractable(extractable
),
231 const blink::WebCryptoKeyFormat format
;
232 const std::vector
<uint8_t> key_data
;
233 const blink::WebCryptoAlgorithm algorithm
;
234 const bool extractable
;
235 const blink::WebCryptoKeyUsageMask usages
;
237 blink::WebCryptoKey key
;
240 struct ExportKeyState
: public BaseState
{
241 ExportKeyState(blink::WebCryptoKeyFormat format
,
242 const blink::WebCryptoKey
& key
,
243 const blink::WebCryptoResult
& result
)
244 : BaseState(result
), format(format
), key(key
) {}
246 const blink::WebCryptoKeyFormat format
;
247 const blink::WebCryptoKey key
;
249 std::vector
<uint8_t> buffer
;
252 typedef EncryptState SignState
;
254 struct VerifySignatureState
: public BaseState
{
255 VerifySignatureState(const blink::WebCryptoAlgorithm
& algorithm
,
256 const blink::WebCryptoKey
& key
,
257 const unsigned char* signature
,
258 unsigned int signature_size
,
259 const unsigned char* data
,
260 unsigned int data_size
,
261 const blink::WebCryptoResult
& result
)
263 algorithm(algorithm
),
265 signature(signature
, signature
+ signature_size
),
266 data(data
, data
+ data_size
),
267 verify_result(false) {}
269 const blink::WebCryptoAlgorithm algorithm
;
270 const blink::WebCryptoKey key
;
271 const std::vector
<uint8_t> signature
;
272 const std::vector
<uint8_t> data
;
277 struct WrapKeyState
: public BaseState
{
278 WrapKeyState(blink::WebCryptoKeyFormat format
,
279 const blink::WebCryptoKey
& key
,
280 const blink::WebCryptoKey
& wrapping_key
,
281 const blink::WebCryptoAlgorithm
& wrap_algorithm
,
282 const blink::WebCryptoResult
& result
)
286 wrapping_key(wrapping_key
),
287 wrap_algorithm(wrap_algorithm
) {}
289 const blink::WebCryptoKeyFormat format
;
290 const blink::WebCryptoKey key
;
291 const blink::WebCryptoKey wrapping_key
;
292 const blink::WebCryptoAlgorithm wrap_algorithm
;
294 std::vector
<uint8_t> buffer
;
297 struct UnwrapKeyState
: public BaseState
{
298 UnwrapKeyState(blink::WebCryptoKeyFormat format
,
299 const unsigned char* wrapped_key
,
300 unsigned wrapped_key_size
,
301 const blink::WebCryptoKey
& wrapping_key
,
302 const blink::WebCryptoAlgorithm
& unwrap_algorithm
,
303 const blink::WebCryptoAlgorithm
& unwrapped_key_algorithm
,
305 blink::WebCryptoKeyUsageMask usages
,
306 const blink::WebCryptoResult
& result
)
309 wrapped_key(wrapped_key
, wrapped_key
+ wrapped_key_size
),
310 wrapping_key(wrapping_key
),
311 unwrap_algorithm(unwrap_algorithm
),
312 unwrapped_key_algorithm(unwrapped_key_algorithm
),
313 extractable(extractable
),
316 const blink::WebCryptoKeyFormat format
;
317 const std::vector
<uint8_t> wrapped_key
;
318 const blink::WebCryptoKey wrapping_key
;
319 const blink::WebCryptoAlgorithm unwrap_algorithm
;
320 const blink::WebCryptoAlgorithm unwrapped_key_algorithm
;
321 const bool extractable
;
322 const blink::WebCryptoKeyUsageMask usages
;
324 blink::WebCryptoKey unwrapped_key
;
327 struct DeriveBitsState
: public BaseState
{
328 DeriveBitsState(const blink::WebCryptoAlgorithm
& algorithm
,
329 const blink::WebCryptoKey
& base_key
,
330 unsigned int length_bits
,
331 const blink::WebCryptoResult
& result
)
333 algorithm(algorithm
),
335 length_bits(length_bits
) {}
337 const blink::WebCryptoAlgorithm algorithm
;
338 const blink::WebCryptoKey base_key
;
339 const unsigned int length_bits
;
341 std::vector
<uint8_t> derived_bytes
;
344 struct DeriveKeyState
: public BaseState
{
345 DeriveKeyState(const blink::WebCryptoAlgorithm
& algorithm
,
346 const blink::WebCryptoKey
& base_key
,
347 const blink::WebCryptoAlgorithm
& import_algorithm
,
348 const blink::WebCryptoAlgorithm
& key_length_algorithm
,
350 blink::WebCryptoKeyUsageMask usages
,
351 const blink::WebCryptoResult
& result
)
353 algorithm(algorithm
),
355 import_algorithm(import_algorithm
),
356 key_length_algorithm(key_length_algorithm
),
357 extractable(extractable
),
360 const blink::WebCryptoAlgorithm algorithm
;
361 const blink::WebCryptoKey base_key
;
362 const blink::WebCryptoAlgorithm import_algorithm
;
363 const blink::WebCryptoAlgorithm key_length_algorithm
;
365 blink::WebCryptoKeyUsageMask usages
;
367 blink::WebCryptoKey derived_key
;
370 // --------------------------------------------------------------------
372 // --------------------------------------------------------------------
374 // * The methods named Do*() run on the crypto thread.
375 // * The methods named Do*Reply() run on the target Blink thread
377 void DoEncryptReply(scoped_ptr
<EncryptState
> state
) {
378 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
381 void DoEncrypt(scoped_ptr
<EncryptState
> passed_state
) {
382 EncryptState
* state
= passed_state
.get();
383 if (state
->cancelled())
386 webcrypto::Encrypt(state
->algorithm
, state
->key
,
387 webcrypto::CryptoData(state
->data
), &state
->buffer
);
388 state
->origin_thread
->PostTask(
389 FROM_HERE
, base::Bind(DoEncryptReply
, Passed(&passed_state
)));
392 void DoDecryptReply(scoped_ptr
<DecryptState
> state
) {
393 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
396 void DoDecrypt(scoped_ptr
<DecryptState
> passed_state
) {
397 DecryptState
* state
= passed_state
.get();
398 if (state
->cancelled())
401 webcrypto::Decrypt(state
->algorithm
, state
->key
,
402 webcrypto::CryptoData(state
->data
), &state
->buffer
);
403 state
->origin_thread
->PostTask(
404 FROM_HERE
, base::Bind(DoDecryptReply
, Passed(&passed_state
)));
407 void DoDigestReply(scoped_ptr
<DigestState
> state
) {
408 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
411 void DoDigest(scoped_ptr
<DigestState
> passed_state
) {
412 DigestState
* state
= passed_state
.get();
413 if (state
->cancelled())
415 state
->status
= webcrypto::Digest(
416 state
->algorithm
, webcrypto::CryptoData(state
->data
), &state
->buffer
);
417 state
->origin_thread
->PostTask(
418 FROM_HERE
, base::Bind(DoDigestReply
, Passed(&passed_state
)));
421 void DoGenerateKeyReply(scoped_ptr
<GenerateKeyState
> state
) {
422 if (state
->status
.IsError()) {
423 CompleteWithError(state
->status
, &state
->result
);
425 state
->generate_key_result
.Complete(&state
->result
);
429 void DoGenerateKey(scoped_ptr
<GenerateKeyState
> passed_state
) {
430 GenerateKeyState
* state
= passed_state
.get();
431 if (state
->cancelled())
434 webcrypto::GenerateKey(state
->algorithm
, state
->extractable
,
435 state
->usages
, &state
->generate_key_result
);
436 state
->origin_thread
->PostTask(
437 FROM_HERE
, base::Bind(DoGenerateKeyReply
, Passed(&passed_state
)));
440 void DoImportKeyReply(scoped_ptr
<ImportKeyState
> state
) {
441 CompleteWithKeyOrError(state
->status
, state
->key
, &state
->result
);
444 void DoImportKey(scoped_ptr
<ImportKeyState
> passed_state
) {
445 ImportKeyState
* state
= passed_state
.get();
446 if (state
->cancelled())
448 state
->status
= webcrypto::ImportKey(
449 state
->format
, webcrypto::CryptoData(state
->key_data
), state
->algorithm
,
450 state
->extractable
, state
->usages
, &state
->key
);
451 if (state
->status
.IsSuccess()) {
452 DCHECK(state
->key
.handle());
453 DCHECK(!state
->key
.algorithm().isNull());
454 DCHECK_EQ(state
->extractable
, state
->key
.extractable());
457 state
->origin_thread
->PostTask(
458 FROM_HERE
, base::Bind(DoImportKeyReply
, Passed(&passed_state
)));
461 void DoExportKeyReply(scoped_ptr
<ExportKeyState
> state
) {
462 if (state
->format
!= blink::WebCryptoKeyFormatJwk
) {
463 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
467 if (state
->status
.IsError()) {
468 CompleteWithError(state
->status
, &state
->result
);
470 state
->result
.completeWithJson(
471 reinterpret_cast<const char*>(vector_as_array(&state
->buffer
)),
472 static_cast<unsigned int>(state
->buffer
.size()));
476 void DoExportKey(scoped_ptr
<ExportKeyState
> passed_state
) {
477 ExportKeyState
* state
= passed_state
.get();
478 if (state
->cancelled())
481 webcrypto::ExportKey(state
->format
, state
->key
, &state
->buffer
);
482 state
->origin_thread
->PostTask(
483 FROM_HERE
, base::Bind(DoExportKeyReply
, Passed(&passed_state
)));
486 void DoSignReply(scoped_ptr
<SignState
> state
) {
487 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
490 void DoSign(scoped_ptr
<SignState
> passed_state
) {
491 SignState
* state
= passed_state
.get();
492 if (state
->cancelled())
495 webcrypto::Sign(state
->algorithm
, state
->key
,
496 webcrypto::CryptoData(state
->data
), &state
->buffer
);
498 state
->origin_thread
->PostTask(
499 FROM_HERE
, base::Bind(DoSignReply
, Passed(&passed_state
)));
502 void DoVerifyReply(scoped_ptr
<VerifySignatureState
> state
) {
503 if (state
->status
.IsError()) {
504 CompleteWithError(state
->status
, &state
->result
);
506 state
->result
.completeWithBoolean(state
->verify_result
);
510 void DoVerify(scoped_ptr
<VerifySignatureState
> passed_state
) {
511 VerifySignatureState
* state
= passed_state
.get();
512 if (state
->cancelled())
514 state
->status
= webcrypto::Verify(
515 state
->algorithm
, state
->key
, webcrypto::CryptoData(state
->signature
),
516 webcrypto::CryptoData(state
->data
), &state
->verify_result
);
518 state
->origin_thread
->PostTask(
519 FROM_HERE
, base::Bind(DoVerifyReply
, Passed(&passed_state
)));
522 void DoWrapKeyReply(scoped_ptr
<WrapKeyState
> state
) {
523 CompleteWithBufferOrError(state
->status
, state
->buffer
, &state
->result
);
526 void DoWrapKey(scoped_ptr
<WrapKeyState
> passed_state
) {
527 WrapKeyState
* state
= passed_state
.get();
528 if (state
->cancelled())
531 webcrypto::WrapKey(state
->format
, state
->key
, state
->wrapping_key
,
532 state
->wrap_algorithm
, &state
->buffer
);
534 state
->origin_thread
->PostTask(
535 FROM_HERE
, base::Bind(DoWrapKeyReply
, Passed(&passed_state
)));
538 void DoUnwrapKeyReply(scoped_ptr
<UnwrapKeyState
> state
) {
539 CompleteWithKeyOrError(state
->status
, state
->unwrapped_key
, &state
->result
);
542 void DoUnwrapKey(scoped_ptr
<UnwrapKeyState
> passed_state
) {
543 UnwrapKeyState
* state
= passed_state
.get();
544 if (state
->cancelled())
546 state
->status
= webcrypto::UnwrapKey(
547 state
->format
, webcrypto::CryptoData(state
->wrapped_key
),
548 state
->wrapping_key
, state
->unwrap_algorithm
,
549 state
->unwrapped_key_algorithm
, state
->extractable
, state
->usages
,
550 &state
->unwrapped_key
);
552 state
->origin_thread
->PostTask(
553 FROM_HERE
, base::Bind(DoUnwrapKeyReply
, Passed(&passed_state
)));
556 void DoDeriveBitsReply(scoped_ptr
<DeriveBitsState
> state
) {
557 CompleteWithBufferOrError(state
->status
, state
->derived_bytes
,
561 void DoDeriveBits(scoped_ptr
<DeriveBitsState
> passed_state
) {
562 DeriveBitsState
* state
= passed_state
.get();
563 if (state
->cancelled())
566 webcrypto::DeriveBits(state
->algorithm
, state
->base_key
,
567 state
->length_bits
, &state
->derived_bytes
);
568 state
->origin_thread
->PostTask(
569 FROM_HERE
, base::Bind(DoDeriveBitsReply
, Passed(&passed_state
)));
572 void DoDeriveKeyReply(scoped_ptr
<DeriveKeyState
> state
) {
573 CompleteWithKeyOrError(state
->status
, state
->derived_key
, &state
->result
);
576 void DoDeriveKey(scoped_ptr
<DeriveKeyState
> passed_state
) {
577 DeriveKeyState
* state
= passed_state
.get();
578 if (state
->cancelled())
580 state
->status
= webcrypto::DeriveKey(
581 state
->algorithm
, state
->base_key
, state
->import_algorithm
,
582 state
->key_length_algorithm
, state
->extractable
, state
->usages
,
583 &state
->derived_key
);
584 state
->origin_thread
->PostTask(
585 FROM_HERE
, base::Bind(DoDeriveKeyReply
, Passed(&passed_state
)));
590 WebCryptoImpl::WebCryptoImpl() {
593 WebCryptoImpl::~WebCryptoImpl() {
596 void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm
& algorithm
,
597 const blink::WebCryptoKey
& key
,
598 const unsigned char* data
,
599 unsigned int data_size
,
600 blink::WebCryptoResult result
) {
601 DCHECK(!algorithm
.isNull());
603 scoped_ptr
<EncryptState
> state(
604 new EncryptState(algorithm
, key
, data
, data_size
, result
));
605 if (!CryptoThreadPool::PostTask(FROM_HERE
,
606 base::Bind(DoEncrypt
, Passed(&state
)))) {
607 CompleteWithThreadPoolError(&result
);
611 void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm
& algorithm
,
612 const blink::WebCryptoKey
& key
,
613 const unsigned char* data
,
614 unsigned int data_size
,
615 blink::WebCryptoResult result
) {
616 DCHECK(!algorithm
.isNull());
618 scoped_ptr
<DecryptState
> state(
619 new DecryptState(algorithm
, key
, data
, data_size
, result
));
620 if (!CryptoThreadPool::PostTask(FROM_HERE
,
621 base::Bind(DoDecrypt
, Passed(&state
)))) {
622 CompleteWithThreadPoolError(&result
);
626 void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm
& algorithm
,
627 const unsigned char* data
,
628 unsigned int data_size
,
629 blink::WebCryptoResult result
) {
630 DCHECK(!algorithm
.isNull());
632 scoped_ptr
<DigestState
> state(new DigestState(
633 algorithm
, blink::WebCryptoKey::createNull(), data
, data_size
, result
));
634 if (!CryptoThreadPool::PostTask(FROM_HERE
,
635 base::Bind(DoDigest
, Passed(&state
)))) {
636 CompleteWithThreadPoolError(&result
);
640 void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm
& algorithm
,
642 blink::WebCryptoKeyUsageMask usages
,
643 blink::WebCryptoResult result
) {
644 DCHECK(!algorithm
.isNull());
646 scoped_ptr
<GenerateKeyState
> state(
647 new GenerateKeyState(algorithm
, extractable
, usages
, result
));
648 if (!CryptoThreadPool::PostTask(FROM_HERE
,
649 base::Bind(DoGenerateKey
, Passed(&state
)))) {
650 CompleteWithThreadPoolError(&result
);
654 void WebCryptoImpl::importKey(blink::WebCryptoKeyFormat format
,
655 const unsigned char* key_data
,
656 unsigned int key_data_size
,
657 const blink::WebCryptoAlgorithm
& algorithm
,
659 blink::WebCryptoKeyUsageMask usages
,
660 blink::WebCryptoResult result
) {
661 scoped_ptr
<ImportKeyState
> state(new ImportKeyState(
662 format
, key_data
, key_data_size
, algorithm
, extractable
, usages
, result
));
663 if (!CryptoThreadPool::PostTask(FROM_HERE
,
664 base::Bind(DoImportKey
, Passed(&state
)))) {
665 CompleteWithThreadPoolError(&result
);
669 void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format
,
670 const blink::WebCryptoKey
& key
,
671 blink::WebCryptoResult result
) {
672 scoped_ptr
<ExportKeyState
> state(new ExportKeyState(format
, key
, result
));
673 if (!CryptoThreadPool::PostTask(FROM_HERE
,
674 base::Bind(DoExportKey
, Passed(&state
)))) {
675 CompleteWithThreadPoolError(&result
);
679 void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm
& algorithm
,
680 const blink::WebCryptoKey
& key
,
681 const unsigned char* data
,
682 unsigned int data_size
,
683 blink::WebCryptoResult result
) {
684 scoped_ptr
<SignState
> state(
685 new SignState(algorithm
, key
, data
, data_size
, result
));
686 if (!CryptoThreadPool::PostTask(FROM_HERE
,
687 base::Bind(DoSign
, Passed(&state
)))) {
688 CompleteWithThreadPoolError(&result
);
692 void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm
& algorithm
,
693 const blink::WebCryptoKey
& key
,
694 const unsigned char* signature
,
695 unsigned int signature_size
,
696 const unsigned char* data
,
697 unsigned int data_size
,
698 blink::WebCryptoResult result
) {
699 scoped_ptr
<VerifySignatureState
> state(new VerifySignatureState(
700 algorithm
, key
, signature
, signature_size
, data
, data_size
, result
));
701 if (!CryptoThreadPool::PostTask(FROM_HERE
,
702 base::Bind(DoVerify
, Passed(&state
)))) {
703 CompleteWithThreadPoolError(&result
);
707 void WebCryptoImpl::wrapKey(blink::WebCryptoKeyFormat format
,
708 const blink::WebCryptoKey
& key
,
709 const blink::WebCryptoKey
& wrapping_key
,
710 const blink::WebCryptoAlgorithm
& wrap_algorithm
,
711 blink::WebCryptoResult result
) {
712 scoped_ptr
<WrapKeyState
> state(
713 new WrapKeyState(format
, key
, wrapping_key
, wrap_algorithm
, result
));
714 if (!CryptoThreadPool::PostTask(FROM_HERE
,
715 base::Bind(DoWrapKey
, Passed(&state
)))) {
716 CompleteWithThreadPoolError(&result
);
720 void WebCryptoImpl::unwrapKey(
721 blink::WebCryptoKeyFormat format
,
722 const unsigned char* wrapped_key
,
723 unsigned wrapped_key_size
,
724 const blink::WebCryptoKey
& wrapping_key
,
725 const blink::WebCryptoAlgorithm
& unwrap_algorithm
,
726 const blink::WebCryptoAlgorithm
& unwrapped_key_algorithm
,
728 blink::WebCryptoKeyUsageMask usages
,
729 blink::WebCryptoResult result
) {
730 scoped_ptr
<UnwrapKeyState
> state(new UnwrapKeyState(
731 format
, wrapped_key
, wrapped_key_size
, wrapping_key
, unwrap_algorithm
,
732 unwrapped_key_algorithm
, extractable
, usages
, result
));
733 if (!CryptoThreadPool::PostTask(FROM_HERE
,
734 base::Bind(DoUnwrapKey
, Passed(&state
)))) {
735 CompleteWithThreadPoolError(&result
);
739 void WebCryptoImpl::deriveBits(const blink::WebCryptoAlgorithm
& algorithm
,
740 const blink::WebCryptoKey
& base_key
,
741 unsigned int length_bits
,
742 blink::WebCryptoResult result
) {
743 scoped_ptr
<DeriveBitsState
> state(
744 new DeriveBitsState(algorithm
, base_key
, length_bits
, result
));
745 if (!CryptoThreadPool::PostTask(FROM_HERE
,
746 base::Bind(DoDeriveBits
, Passed(&state
)))) {
747 CompleteWithThreadPoolError(&result
);
751 void WebCryptoImpl::deriveKey(
752 const blink::WebCryptoAlgorithm
& algorithm
,
753 const blink::WebCryptoKey
& base_key
,
754 const blink::WebCryptoAlgorithm
& import_algorithm
,
755 const blink::WebCryptoAlgorithm
& key_length_algorithm
,
757 blink::WebCryptoKeyUsageMask usages
,
758 blink::WebCryptoResult result
) {
759 scoped_ptr
<DeriveKeyState
> state(
760 new DeriveKeyState(algorithm
, base_key
, import_algorithm
,
761 key_length_algorithm
, extractable
, usages
, result
));
762 if (!CryptoThreadPool::PostTask(FROM_HERE
,
763 base::Bind(DoDeriveKey
, Passed(&state
)))) {
764 CompleteWithThreadPoolError(&result
);
768 blink::WebCryptoDigestor
* WebCryptoImpl::createDigestor(
769 blink::WebCryptoAlgorithmId algorithm_id
) {
770 return webcrypto::CreateDigestor(algorithm_id
).release();
773 bool WebCryptoImpl::deserializeKeyForClone(
774 const blink::WebCryptoKeyAlgorithm
& algorithm
,
775 blink::WebCryptoKeyType type
,
777 blink::WebCryptoKeyUsageMask usages
,
778 const unsigned char* key_data
,
779 unsigned key_data_size
,
780 blink::WebCryptoKey
& key
) {
781 return webcrypto::DeserializeKeyForClone(
782 algorithm
, type
, extractable
, usages
,
783 webcrypto::CryptoData(key_data
, key_data_size
), &key
);
786 bool WebCryptoImpl::serializeKeyForClone(
787 const blink::WebCryptoKey
& key
,
788 blink::WebVector
<unsigned char>& key_data
) {
789 return webcrypto::SerializeKeyForClone(key
, &key_data
);
792 } // namespace webcrypto