1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/webcrypto/webcrypto_impl.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/bind.h" 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/lazy_instance.h" 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/location.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h" 11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/memory/scoped_ptr.h" 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/single_thread_task_runner.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/stl_util.h" 145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/task_runner.h" 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/thread_task_runner_handle.h" 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/threading/sequenced_worker_pool.h" 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/threading/worker_pool.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/algorithm_dispatch.h" 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/webcrypto/crypto_data.h" 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/child/webcrypto/status.h" 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/structured_clone.h" 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/webcrypto/webcrypto_util.h" 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/child/worker_thread_task_runner.h" 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h" 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content { 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using webcrypto::Status; 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// --------------------- 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Threading 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// --------------------- 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// WebCrypto operations can be slow. For instance generating an RSA key can 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// take hundreds of milliseconds to several seconds. 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Moreover the underlying crypto libraries are not threadsafe when operating 415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// on the same key. 425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// The strategy used here is to run a sequenced worker pool for all WebCrypto 445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// operations. This pool (of 1 threads) is also used by requests started from 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Blink Web Workers. 465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// A few notes to keep in mind: 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// * PostTaskAndReply() cannot be used for two reasons: 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// (1) Blink web worker threads do not have an associated message loop so 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// construction of the reply callback will crash. 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// (2) PostTaskAndReply() handles failure posting the reply by leaking the 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// callback, rather than destroying it. In the case of Web Workers this 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// condition is reachable via normal execution, since Web Workers can 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// be stopped before the WebCrypto operation has finished. A policy of 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// leaking would therefore be problematic. 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// * blink::WebArrayBuffer is NOT threadsafe, and should therefore be allocated 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// on the target Blink thread. 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// TODO(eroman): Is there any way around this? Copying the result between 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// threads is silly. 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// * WebCryptoAlgorithm and WebCryptoKey are threadsafe (however the key's 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// handle(), which wraps an NSS/OpenSSL type, may not be and should only be 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// used from the webcrypto thread). 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// * blink::WebCryptoResult is not threadsafe and should only be operated on 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// the target Blink thread. HOWEVER, it is safe to delete it from any thread. 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This can happen if by the time the operation has completed in the crypto 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// worker pool, the Blink worker thread that initiated the request is gone. 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Posting back to the origin thread will fail, and the WebCryptoResult will 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// be deleted while running in the crypto worker pool. 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass CryptoThreadPool { 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CryptoThreadPool() 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : worker_pool_(new base::SequencedWorkerPool(1, "WebCrypto")), 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu task_runner_(worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior( 815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu worker_pool_->GetSequenceToken(), 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) {} 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static bool PostTask(const tracked_objects::Location& from_here, 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const base::Closure& task); 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_refptr<base::SequencedWorkerPool> worker_pool_; 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_refptr<base::SequencedTaskRunner> task_runner_; 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubase::LazyInstance<CryptoThreadPool>::Leaky crypto_thread_pool = 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LAZY_INSTANCE_INITIALIZER; 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool CryptoThreadPool::PostTask(const tracked_objects::Location& from_here, 965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const base::Closure& task) { 975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return crypto_thread_pool.Get().task_runner_->PostTask(from_here, task); 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CompleteWithThreadPoolError(blink::WebCryptoResult* result) { 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result->completeWithError(blink::WebCryptoErrorTypeOperation, 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "Failed posting to crypto worker pool"); 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CompleteWithError(const Status& status, blink::WebCryptoResult* result) { 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(status.IsError()); 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result->completeWithError(status.error_type(), 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebString::fromUTF8(status.error_details())); 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CompleteWithBufferOrError(const Status& status, 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<uint8_t>& buffer, 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoResult* result) { 1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (status.IsError()) { 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithError(status, result); 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (buffer.size() > UINT_MAX) { 1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // WebArrayBuffers have a smaller range than std::vector<>, so 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // theoretically this could overflow. 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithError(Status::ErrorUnexpected(), result); 1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result->completeWithBuffer(vector_as_array(&buffer), buffer.size()); 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CompleteWithKeyOrError(const Status& status, 1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey& key, 1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoResult* result) { 1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (status.IsError()) { 1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithError(status, result); 1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result->completeWithKey(key); 1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Gets a task runner for the current thread. The current thread is either: 1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// * The main Blink thread 1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// * A Blink web worker thread 1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// A different mechanism is needed for posting to these threads. The main 1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// thread has an associated message loop and can simply use 1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// base::ThreadTaskRunnerHandle. Whereas the web worker threads are managed by 1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Blink and need to be indirected through WorkerThreadTaskRunner. 1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuscoped_refptr<base::TaskRunner> GetCurrentBlinkThread() { 1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (base::ThreadTaskRunnerHandle::IsSet()) 1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return base::ThreadTaskRunnerHandle::Get(); 1505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return WorkerThreadTaskRunner::current(); 1515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// -------------------------------------------------------------------- 1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// State 1555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// -------------------------------------------------------------------- 1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Explicit state classes are used rather than base::Bind(). This is done 1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// both for clarity, but also to avoid extraneous allocations for things 1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// like passing buffers and result objects between threads. 1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// BaseState is the base class common to all of the async operations, and 1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// keeps track of the thread to complete on, the error state, and the 1635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// callback into Blink. 1645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Ownership of the State object is passed between the crypto thread and the 1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Blink thread. Under normal completion it is destroyed on the Blink thread. 1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// However it may also be destroyed on the crypto thread if the Blink thread 1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// has vanished (which can happen for Blink web worker threads). 1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct BaseState { 1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu explicit BaseState(const blink::WebCryptoResult& result) 1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : origin_thread(GetCurrentBlinkThread()), result(result) {} 1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool cancelled() { 1756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return result.cancelled(); 1766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 1776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_refptr<base::TaskRunner> origin_thread; 1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu webcrypto::Status status; 1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoResult result; 1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu protected: 1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Since there is no virtual destructor, must not delete directly as a 1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // BaseState. 1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ~BaseState() {} 1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct EncryptState : public BaseState { 1905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EncryptState(const blink::WebCryptoAlgorithm& algorithm, 1915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey& key, 1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const unsigned char* data, 1935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unsigned int data_size, 1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoResult& result) 1955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : BaseState(result), 1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu algorithm(algorithm), 1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu key(key), 1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu data(data, data + data_size) {} 1995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm algorithm; 2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey key; 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<uint8_t> data; 2035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<uint8_t> buffer; 2055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 2065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutypedef EncryptState DecryptState; 2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutypedef EncryptState DigestState; 2095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct GenerateKeyState : public BaseState { 2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GenerateKeyState(const blink::WebCryptoAlgorithm& algorithm, 2125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool extractable, 2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoKeyUsageMask usage_mask, 2145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoResult& result) 2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : BaseState(result), 2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu algorithm(algorithm), 2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu extractable(extractable), 2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu usage_mask(usage_mask), 2195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public_key(blink::WebCryptoKey::createNull()), 2205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private_key(blink::WebCryptoKey::createNull()), 2215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu is_asymmetric(false) {} 2225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm algorithm; 2245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const bool extractable; 2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKeyUsageMask usage_mask; 2265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If |is_asymmetric| is false, then |public_key| is understood to mean the 2285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // symmetric key, and |private_key| is unused. 2295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoKey public_key; 2305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoKey private_key; 2315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool is_asymmetric; 2325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 2335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct ImportKeyState : public BaseState { 2355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ImportKeyState(blink::WebCryptoKeyFormat format, 2365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const unsigned char* key_data, 2375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unsigned int key_data_size, 2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm& algorithm, 2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool extractable, 2405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoKeyUsageMask usage_mask, 2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoResult& result) 2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : BaseState(result), 2435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu format(format), 2445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu key_data(key_data, key_data + key_data_size), 2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu algorithm(algorithm), 2465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu extractable(extractable), 2475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu usage_mask(usage_mask), 2485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu key(blink::WebCryptoKey::createNull()) {} 2495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKeyFormat format; 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<uint8_t> key_data; 2525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm algorithm; 2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const bool extractable; 2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKeyUsageMask usage_mask; 2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoKey key; 2575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 2585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct ExportKeyState : public BaseState { 2605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ExportKeyState(blink::WebCryptoKeyFormat format, 2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey& key, 2625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoResult& result) 2635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : BaseState(result), format(format), key(key) {} 2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKeyFormat format; 2665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey key; 2675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<uint8_t> buffer; 2695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 2705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutypedef EncryptState SignState; 2725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct VerifySignatureState : public BaseState { 2745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VerifySignatureState(const blink::WebCryptoAlgorithm& algorithm, 2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey& key, 2765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const unsigned char* signature, 2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unsigned int signature_size, 2785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const unsigned char* data, 2795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unsigned int data_size, 2805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoResult& result) 2815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : BaseState(result), 2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu algorithm(algorithm), 2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu key(key), 2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu signature(signature, signature + signature_size), 2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu data(data, data + data_size), 2865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu verify_result(false) {} 2875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm algorithm; 2895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey key; 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<uint8_t> signature; 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<uint8_t> data; 2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool verify_result; 2945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct WrapKeyState : public BaseState { 2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu WrapKeyState(blink::WebCryptoKeyFormat format, 2985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey& key, 2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey& wrapping_key, 3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm& wrap_algorithm, 3015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoResult& result) 3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : BaseState(result), 3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu format(format), 3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu key(key), 3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wrapping_key(wrapping_key), 3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wrap_algorithm(wrap_algorithm) {} 3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKeyFormat format; 3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey key; 3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey wrapping_key; 3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm wrap_algorithm; 3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<uint8_t> buffer; 3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct UnwrapKeyState : public BaseState { 3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UnwrapKeyState(blink::WebCryptoKeyFormat format, 3185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const unsigned char* wrapped_key, 3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unsigned wrapped_key_size, 3205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey& wrapping_key, 3215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm& unwrap_algorithm, 3225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm& unwrapped_key_algorithm, 3235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool extractable, 3245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoKeyUsageMask usages, 3255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoResult& result) 3265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : BaseState(result), 3275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu format(format), 3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wrapped_key(wrapped_key, wrapped_key + wrapped_key_size), 3295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wrapping_key(wrapping_key), 3305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unwrap_algorithm(unwrap_algorithm), 3315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unwrapped_key_algorithm(unwrapped_key_algorithm), 3325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu extractable(extractable), 3335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu usages(usages), 3345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unwrapped_key(blink::WebCryptoKey::createNull()) {} 3355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKeyFormat format; 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<uint8_t> wrapped_key; 3385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKey wrapping_key; 3395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm unwrap_algorithm; 3405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoAlgorithm unwrapped_key_algorithm; 3415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const bool extractable; 3425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const blink::WebCryptoKeyUsageMask usages; 3435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoKey unwrapped_key; 3455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 3465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// -------------------------------------------------------------------- 3485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Wrapper functions 3495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// -------------------------------------------------------------------- 3505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 3515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// * The methods named Do*() run on the crypto thread. 3525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// * The methods named Do*Reply() run on the target Blink thread 3535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoEncryptReply(scoped_ptr<EncryptState> state) { 3555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithBufferOrError(state->status, state->buffer, &state->result); 3565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoEncrypt(scoped_ptr<EncryptState> passed_state) { 3595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EncryptState* state = passed_state.get(); 3606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 3616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 3625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = webcrypto::Encrypt(state->algorithm, 3635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->key, 3645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu webcrypto::CryptoData(state->data), 3655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &state->buffer); 3665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 3675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoEncryptReply, Passed(&passed_state))); 3685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoDecryptReply(scoped_ptr<DecryptState> state) { 3715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithBufferOrError(state->status, state->buffer, &state->result); 3725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoDecrypt(scoped_ptr<DecryptState> passed_state) { 3755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DecryptState* state = passed_state.get(); 3766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 3776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 3785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = webcrypto::Decrypt(state->algorithm, 3795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->key, 3805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu webcrypto::CryptoData(state->data), 3815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &state->buffer); 3825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 3835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoDecryptReply, Passed(&passed_state))); 3845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoDigestReply(scoped_ptr<DigestState> state) { 3875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithBufferOrError(state->status, state->buffer, &state->result); 3885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoDigest(scoped_ptr<DigestState> passed_state) { 3915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DigestState* state = passed_state.get(); 3926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 3936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 3945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = webcrypto::Digest( 3955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->algorithm, webcrypto::CryptoData(state->data), &state->buffer); 3965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 3975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoDigestReply, Passed(&passed_state))); 3985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoGenerateKeyReply(scoped_ptr<GenerateKeyState> state) { 4015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (state->status.IsError()) { 4025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithError(state->status, &state->result); 4035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 4045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (state->is_asymmetric) 4055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->result.completeWithKeyPair(state->public_key, state->private_key); 4065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu else 4075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->result.completeWithKey(state->public_key); 4085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 4095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoGenerateKey(scoped_ptr<GenerateKeyState> passed_state) { 4125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GenerateKeyState* state = passed_state.get(); 4136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 4146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->is_asymmetric = 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) webcrypto::IsAlgorithmAsymmetric(state->algorithm.id()); 4175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (state->is_asymmetric) { 4185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = webcrypto::GenerateKeyPair(state->algorithm, 4195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->extractable, 4205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->usage_mask, 4215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &state->public_key, 4225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &state->private_key); 4235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (state->status.IsSuccess()) { 4255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(state->public_key.handle()); 4265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(state->private_key.handle()); 4275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_EQ(state->algorithm.id(), state->public_key.algorithm().id()); 4285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_EQ(state->algorithm.id(), state->private_key.algorithm().id()); 4295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_EQ(true, state->public_key.extractable()); 4305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_EQ(state->extractable, state->private_key.extractable()); 4315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 4325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 4335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blink::WebCryptoKey* key = &state->public_key; 4345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = webcrypto::GenerateSecretKey( 4365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->algorithm, state->extractable, state->usage_mask, key); 4375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (state->status.IsSuccess()) { 4395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(key->handle()); 4405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_EQ(state->algorithm.id(), key->algorithm().id()); 4415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_EQ(state->extractable, key->extractable()); 4425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_EQ(state->usage_mask, key->usages()); 4435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 4445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 4455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 4475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoGenerateKeyReply, Passed(&passed_state))); 4485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoImportKeyReply(scoped_ptr<ImportKeyState> state) { 4515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithKeyOrError(state->status, state->key, &state->result); 4525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoImportKey(scoped_ptr<ImportKeyState> passed_state) { 4555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ImportKeyState* state = passed_state.get(); 4566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 4576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 4585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = webcrypto::ImportKey(state->format, 4595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu webcrypto::CryptoData(state->key_data), 4605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->algorithm, 4615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->extractable, 4625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->usage_mask, 4635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &state->key); 4645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (state->status.IsSuccess()) { 4655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(state->key.handle()); 4665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(!state->key.algorithm().isNull()); 4675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_EQ(state->extractable, state->key.extractable()); 4685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 4695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 4715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoImportKeyReply, Passed(&passed_state))); 4725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoExportKeyReply(scoped_ptr<ExportKeyState> state) { 475f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (state->format != blink::WebCryptoKeyFormatJwk) { 476f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CompleteWithBufferOrError(state->status, state->buffer, &state->result); 477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 478f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 479f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 480f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (state->status.IsError()) { 481f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CompleteWithError(state->status, &state->result); 482f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 483f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) state->result.completeWithJson( 4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reinterpret_cast<const char*>(vector_as_array(&state->buffer)), 485f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) state->buffer.size()); 486f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 4875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoExportKey(scoped_ptr<ExportKeyState> passed_state) { 4905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ExportKeyState* state = passed_state.get(); 4916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 4926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 4935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = 4945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu webcrypto::ExportKey(state->format, state->key, &state->buffer); 4955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 4965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoExportKeyReply, Passed(&passed_state))); 4975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoSignReply(scoped_ptr<SignState> state) { 5005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithBufferOrError(state->status, state->buffer, &state->result); 5015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoSign(scoped_ptr<SignState> passed_state) { 5045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SignState* state = passed_state.get(); 5056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 5066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 5075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = webcrypto::Sign(state->algorithm, 5085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->key, 5095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu webcrypto::CryptoData(state->data), 5105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &state->buffer); 5115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 5135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoSignReply, Passed(&passed_state))); 5145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoVerifyReply(scoped_ptr<VerifySignatureState> state) { 5175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (state->status.IsError()) { 5185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithError(state->status, &state->result); 5195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 5205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->result.completeWithBoolean(state->verify_result); 5215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 5225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoVerify(scoped_ptr<VerifySignatureState> passed_state) { 5255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VerifySignatureState* state = passed_state.get(); 5266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 5276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->status = webcrypto::Verify(state->algorithm, 5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->key, 5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) webcrypto::CryptoData(state->signature), 5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) webcrypto::CryptoData(state->data), 5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &state->verify_result); 5335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 5355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoVerifyReply, Passed(&passed_state))); 5365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoWrapKeyReply(scoped_ptr<WrapKeyState> state) { 5395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithBufferOrError(state->status, state->buffer, &state->result); 5405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoWrapKey(scoped_ptr<WrapKeyState> passed_state) { 5435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu WrapKeyState* state = passed_state.get(); 5446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 5456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 5465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = webcrypto::WrapKey(state->format, 5475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->key, 548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->wrapping_key, 5495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->wrap_algorithm, 5505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &state->buffer); 5515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 5535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoWrapKeyReply, Passed(&passed_state))); 5545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoUnwrapKeyReply(scoped_ptr<UnwrapKeyState> state) { 5575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithKeyOrError(state->status, state->unwrapped_key, &state->result); 5585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DoUnwrapKey(scoped_ptr<UnwrapKeyState> passed_state) { 5615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UnwrapKeyState* state = passed_state.get(); 5626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (state->cancelled()) 5636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 5645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->status = 5655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu webcrypto::UnwrapKey(state->format, 5665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu webcrypto::CryptoData(state->wrapped_key), 5675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->wrapping_key, 5685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->unwrap_algorithm, 5695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->unwrapped_key_algorithm, 5705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->extractable, 5715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->usages, 5725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &state->unwrapped_key); 5735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu state->origin_thread->PostTask( 5755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, base::Bind(DoUnwrapKeyReply, Passed(&passed_state))); 5765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuWebCryptoImpl::WebCryptoImpl() { 5815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuWebCryptoImpl::~WebCryptoImpl() { 5845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm& algorithm, 587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const blink::WebCryptoKey& key, 588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const unsigned char* data, 589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unsigned int data_size, 590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebCryptoResult result) { 591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!algorithm.isNull()); 5925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<EncryptState> state( 5945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new EncryptState(algorithm, key, data, data_size, result)); 5955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 5965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoEncrypt, Passed(&state)))) { 5975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 5985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm& algorithm, 602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const blink::WebCryptoKey& key, 603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const unsigned char* data, 604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unsigned int data_size, 605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebCryptoResult result) { 606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!algorithm.isNull()); 6075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 6085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<DecryptState> state( 6095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new DecryptState(algorithm, key, data, data_size, result)); 6105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 6115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoDecrypt, Passed(&state)))) { 6125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 6135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm, 617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const unsigned char* data, 618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unsigned int data_size, 619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebCryptoResult result) { 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!algorithm.isNull()); 6215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 6225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<DigestState> state(new DigestState( 6235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu algorithm, blink::WebCryptoKey::createNull(), data, data_size, result)); 6245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 6255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoDigest, Passed(&state)))) { 6265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 6275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm, 631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool extractable, 632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebCryptoKeyUsageMask usage_mask, 633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebCryptoResult result) { 634a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!algorithm.isNull()); 6355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 6365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<GenerateKeyState> state( 6375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new GenerateKeyState(algorithm, extractable, usage_mask, result)); 6385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 6395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoGenerateKey, Passed(&state)))) { 6405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 64423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void WebCryptoImpl::importKey(blink::WebCryptoKeyFormat format, 64523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const unsigned char* key_data, 64623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) unsigned int key_data_size, 64723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const blink::WebCryptoAlgorithm& algorithm, 64823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool extractable, 64923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) blink::WebCryptoKeyUsageMask usage_mask, 65023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) blink::WebCryptoResult result) { 6515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<ImportKeyState> state(new ImportKeyState(format, 6525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu key_data, 6535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu key_data_size, 6545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu algorithm, 6555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu extractable, 6565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu usage_mask, 6575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result)); 6585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 6595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoImportKey, Passed(&state)))) { 6605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 661a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 662a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 664a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format, 665a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const blink::WebCryptoKey& key, 666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebCryptoResult result) { 6675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<ExportKeyState> state(new ExportKeyState(format, key, result)); 6685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 6695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoExportKey, Passed(&state)))) { 6705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 6715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm& algorithm, 675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const blink::WebCryptoKey& key, 676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const unsigned char* data, 677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unsigned int data_size, 678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebCryptoResult result) { 6795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<SignState> state( 6805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new SignState(algorithm, key, data, data_size, result)); 6815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 6825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoSign, Passed(&state)))) { 6835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 6845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm& algorithm, 688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const blink::WebCryptoKey& key, 689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const unsigned char* signature, 690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unsigned int signature_size, 691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const unsigned char* data, 692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unsigned int data_size, 693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebCryptoResult result) { 6945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<VerifySignatureState> state(new VerifySignatureState( 6955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu algorithm, key, signature, signature_size, data, data_size, result)); 6965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 6975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoVerify, Passed(&state)))) { 6985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 6995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 700a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 701a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 702effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid WebCryptoImpl::wrapKey(blink::WebCryptoKeyFormat format, 703effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const blink::WebCryptoKey& key, 704effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const blink::WebCryptoKey& wrapping_key, 705effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const blink::WebCryptoAlgorithm& wrap_algorithm, 706effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebCryptoResult result) { 7075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<WrapKeyState> state( 7085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new WrapKeyState(format, key, wrapping_key, wrap_algorithm, result)); 7095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 7105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoWrapKey, Passed(&state)))) { 7115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 7125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 713effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 714effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 715effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid WebCryptoImpl::unwrapKey( 716effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebCryptoKeyFormat format, 717effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const unsigned char* wrapped_key, 718effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch unsigned wrapped_key_size, 719effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const blink::WebCryptoKey& wrapping_key, 720effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const blink::WebCryptoAlgorithm& unwrap_algorithm, 721effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const blink::WebCryptoAlgorithm& unwrapped_key_algorithm, 722effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool extractable, 723effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebCryptoKeyUsageMask usages, 724effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebCryptoResult result) { 7255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<UnwrapKeyState> state(new UnwrapKeyState(format, 7265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wrapped_key, 7275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wrapped_key_size, 7285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wrapping_key, 7295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unwrap_algorithm, 7305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unwrapped_key_algorithm, 7315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu extractable, 7325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu usages, 7335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result)); 7345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!CryptoThreadPool::PostTask(FROM_HERE, 7355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(DoUnwrapKey, Passed(&state)))) { 7365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CompleteWithThreadPoolError(&result); 7375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 740e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochblink::WebCryptoDigestor* WebCryptoImpl::createDigestor( 741e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch blink::WebCryptoAlgorithmId algorithm_id) { 742e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return webcrypto::CreateDigestor(algorithm_id).release(); 743e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 744e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 74523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool WebCryptoImpl::deserializeKeyForClone( 74623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const blink::WebCryptoKeyAlgorithm& algorithm, 74723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) blink::WebCryptoKeyType type, 74823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool extractable, 74923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) blink::WebCryptoKeyUsageMask usages, 75023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const unsigned char* key_data, 75123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) unsigned key_data_size, 75223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) blink::WebCryptoKey& key) { 7535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // TODO(eroman): Rather than do the import immediately on the current thread, 7545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // it could defer to the crypto thread. 7555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return webcrypto::DeserializeKeyForClone( 75623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) algorithm, 75723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) type, 75823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) extractable, 75923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) usages, 76023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) webcrypto::CryptoData(key_data, key_data_size), 76123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &key); 76223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 76323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 76423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool WebCryptoImpl::serializeKeyForClone( 76523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const blink::WebCryptoKey& key, 76623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) blink::WebVector<unsigned char>& key_data) { 7675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return webcrypto::SerializeKeyForClone(key, &key_data); 76823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 76923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 770a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace content 771