webcrypto_impl.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  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.
  4. #include "components/webcrypto/webcrypto_impl.h"
  5. #include <limits.h>
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <utility>
  9. #include "base/bind.h"
  10. #include "base/check_op.h"
  11. #include "base/containers/span.h"
  12. #include "base/lazy_instance.h"
  13. #include "base/location.h"
  14. #include "base/task/single_thread_task_runner.h"
  15. #include "base/task/task_runner.h"
  16. #include "base/threading/thread.h"
  17. #include "base/threading/thread_task_runner_handle.h"
  18. #include "base/trace_event/trace_event.h"
  19. #include "components/webcrypto/algorithm_dispatch.h"
  20. #include "components/webcrypto/generate_key_result.h"
  21. #include "components/webcrypto/status.h"
  22. #include "third_party/blink/public/platform/web_crypto_key_algorithm.h"
  23. #include "third_party/blink/public/platform/web_string.h"
  24. namespace webcrypto {
  25. using webcrypto::Status;
  26. namespace {
  27. // ---------------------
  28. // Threading
  29. // ---------------------
  30. //
  31. // WebCrypto operations can be slow. For instance generating an RSA key can
  32. // take seconds.
  33. //
  34. // The strategy used here is to run a worker pool for all WebCrypto operations
  35. // (except structured cloning). This same pool is also used by requests started
  36. // from Blink Web Workers.
  37. //
  38. // A few notes to keep in mind:
  39. //
  40. // * PostTaskAndReply() is not used because of how it handles failures -- it
  41. // leaks the callback when failing to post back to the origin thread.
  42. //
  43. // This is a problem since WebCrypto may be called from WebWorker threads,
  44. // which may be aborted at any time. Leaking would be undesirable, and
  45. // reachable in practice.
  46. //
  47. // * blink::WebArrayBuffer is NOT threadsafe, and should therefore be allocated
  48. // only on the target Blink thread.
  49. //
  50. // TODO(eroman): Is there any way around this? Copying the result between
  51. // threads is silly.
  52. //
  53. // * WebCryptoAlgorithm and WebCryptoKey are threadsafe, by virtue of being
  54. // immutable. Internally asymmetric WebCryptoKeys wrap BoringSSL's EVP_PKEY.
  55. // These are safe to use for BoringSSL operations across threads, provided
  56. // the internals of the EVP_PKEY are not mutated (they never should be
  57. // following ImportKey()).
  58. //
  59. // * blink::WebCryptoResult is not threadsafe and should only be operated on
  60. // the target Blink thread. HOWEVER, it is safe to delete it from any thread.
  61. // This can happen if by the time the operation has completed in the crypto
  62. // worker pool, the Blink worker thread that initiated the request is gone.
  63. // Posting back to the origin thread will fail, and the WebCryptoResult will
  64. // be deleted while running in the crypto worker pool.
  65. class CryptoThreadPool {
  66. public:
  67. CryptoThreadPool() : worker_thread_("WebCrypto") {
  68. base::Thread::Options options;
  69. options.joinable = false;
  70. worker_thread_.StartWithOptions(std::move(options));
  71. }
  72. CryptoThreadPool(const CryptoThreadPool&) = delete;
  73. CryptoThreadPool& operator=(const CryptoThreadPool&) = delete;
  74. static bool PostTask(const base::Location& from_here, base::OnceClosure task);
  75. private:
  76. // TODO(gab): the pool is currently using a single non-joinable thread to
  77. // mimic the old behavior of using a CONTINUE_ON_SHUTDOWN SequencedTaskRunner
  78. // on a single-threaded SequencedWorkerPool, but we'd like to consider using
  79. // the ThreadPool here and allowing multiple threads (SEQUENCED or even
  80. // PARALLEL ExecutionMode: http://crbug.com/623700).
  81. base::Thread worker_thread_;
  82. };
  83. base::LazyInstance<CryptoThreadPool>::Leaky crypto_thread_pool =
  84. LAZY_INSTANCE_INITIALIZER;
  85. bool CryptoThreadPool::PostTask(const base::Location& from_here,
  86. base::OnceClosure task) {
  87. return crypto_thread_pool.Get().worker_thread_.task_runner()->PostTask(
  88. from_here, std::move(task));
  89. }
  90. void CompleteWithThreadPoolError(blink::WebCryptoResult* result) {
  91. result->CompleteWithError(blink::kWebCryptoErrorTypeOperation,
  92. "Failed posting to crypto worker pool");
  93. }
  94. void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
  95. DCHECK(status.IsError());
  96. result->CompleteWithError(status.error_type(),
  97. blink::WebString::FromUTF8(status.error_details()));
  98. }
  99. void CompleteWithBufferOrError(const Status& status,
  100. const std::vector<uint8_t>& buffer,
  101. blink::WebCryptoResult* result) {
  102. if (status.IsError()) {
  103. CompleteWithError(status, result);
  104. } else {
  105. if (buffer.size() > UINT_MAX) {
  106. // WebArrayBuffers have a smaller range than std::vector<>, so
  107. // theoretically this could overflow.
  108. CompleteWithError(Status::ErrorUnexpected(), result);
  109. } else {
  110. result->CompleteWithBuffer(buffer.data(),
  111. static_cast<unsigned int>(buffer.size()));
  112. }
  113. }
  114. }
  115. void CompleteWithKeyOrError(const Status& status,
  116. const blink::WebCryptoKey& key,
  117. blink::WebCryptoResult* result) {
  118. if (status.IsError()) {
  119. CompleteWithError(status, result);
  120. } else {
  121. result->CompleteWithKey(key);
  122. }
  123. }
  124. // --------------------------------------------------------------------
  125. // State
  126. // --------------------------------------------------------------------
  127. //
  128. // Explicit state classes are used rather than base::Bind{Once,Repeating}. This
  129. // is done both for clarity, but also to avoid extraneous allocations for things
  130. // like passing buffers and result objects between threads.
  131. //
  132. // BaseState is the base class common to all of the async operations, and
  133. // keeps track of the thread to complete on, the error state, and the
  134. // callback into Blink.
  135. //
  136. // Ownership of the State object is passed between the crypto thread and the
  137. // Blink thread. Under normal completion it is destroyed on the Blink thread.
  138. // However it may also be destroyed on the crypto thread if the Blink thread
  139. // has vanished (which can happen for Blink web worker threads).
  140. struct BaseState {
  141. BaseState(const blink::WebCryptoResult& result,
  142. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  143. : origin_thread(task_runner), result(result) {}
  144. bool cancelled() { return result.Cancelled(); }
  145. scoped_refptr<base::TaskRunner> origin_thread;
  146. webcrypto::Status status;
  147. blink::WebCryptoResult result;
  148. protected:
  149. // Since there is no virtual destructor, must not delete directly as a
  150. // BaseState.
  151. ~BaseState() {}
  152. };
  153. struct EncryptState : public BaseState {
  154. EncryptState(const blink::WebCryptoAlgorithm& algorithm,
  155. const blink::WebCryptoKey& key,
  156. blink::WebVector<unsigned char> data,
  157. const blink::WebCryptoResult& result,
  158. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  159. : BaseState(result, std::move(task_runner)),
  160. algorithm(algorithm),
  161. key(key),
  162. data(std::move(data)) {}
  163. const blink::WebCryptoAlgorithm algorithm;
  164. const blink::WebCryptoKey key;
  165. const blink::WebVector<unsigned char> data;
  166. std::vector<uint8_t> buffer;
  167. };
  168. typedef EncryptState DecryptState;
  169. typedef EncryptState DigestState;
  170. struct GenerateKeyState : public BaseState {
  171. GenerateKeyState(const blink::WebCryptoAlgorithm& algorithm,
  172. bool extractable,
  173. blink::WebCryptoKeyUsageMask usages,
  174. const blink::WebCryptoResult& result,
  175. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  176. : BaseState(result, std::move(task_runner)),
  177. algorithm(algorithm),
  178. extractable(extractable),
  179. usages(usages) {}
  180. const blink::WebCryptoAlgorithm algorithm;
  181. const bool extractable;
  182. const blink::WebCryptoKeyUsageMask usages;
  183. webcrypto::GenerateKeyResult generate_key_result;
  184. };
  185. struct ImportKeyState : public BaseState {
  186. ImportKeyState(blink::WebCryptoKeyFormat format,
  187. blink::WebVector<unsigned char> key_data,
  188. const blink::WebCryptoAlgorithm& algorithm,
  189. bool extractable,
  190. blink::WebCryptoKeyUsageMask usages,
  191. const blink::WebCryptoResult& result,
  192. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  193. : BaseState(result, std::move(task_runner)),
  194. format(format),
  195. key_data(std::move(key_data)),
  196. algorithm(algorithm),
  197. extractable(extractable),
  198. usages(usages) {}
  199. const blink::WebCryptoKeyFormat format;
  200. const blink::WebVector<unsigned char> key_data;
  201. const blink::WebCryptoAlgorithm algorithm;
  202. const bool extractable;
  203. const blink::WebCryptoKeyUsageMask usages;
  204. blink::WebCryptoKey key;
  205. };
  206. struct ExportKeyState : public BaseState {
  207. ExportKeyState(blink::WebCryptoKeyFormat format,
  208. const blink::WebCryptoKey& key,
  209. const blink::WebCryptoResult& result,
  210. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  211. : BaseState(result, std::move(task_runner)), format(format), key(key) {}
  212. const blink::WebCryptoKeyFormat format;
  213. const blink::WebCryptoKey key;
  214. std::vector<uint8_t> buffer;
  215. };
  216. typedef EncryptState SignState;
  217. struct VerifySignatureState : public BaseState {
  218. VerifySignatureState(const blink::WebCryptoAlgorithm& algorithm,
  219. const blink::WebCryptoKey& key,
  220. blink::WebVector<unsigned char> signature,
  221. blink::WebVector<unsigned char> data,
  222. const blink::WebCryptoResult& result,
  223. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  224. : BaseState(result, std::move(task_runner)),
  225. algorithm(algorithm),
  226. key(key),
  227. signature(std::move(signature)),
  228. data(std::move(data)),
  229. verify_result(false) {}
  230. const blink::WebCryptoAlgorithm algorithm;
  231. const blink::WebCryptoKey key;
  232. blink::WebVector<unsigned char> signature;
  233. blink::WebVector<unsigned char> data;
  234. bool verify_result;
  235. };
  236. struct WrapKeyState : public BaseState {
  237. WrapKeyState(blink::WebCryptoKeyFormat format,
  238. const blink::WebCryptoKey& key,
  239. const blink::WebCryptoKey& wrapping_key,
  240. const blink::WebCryptoAlgorithm& wrap_algorithm,
  241. const blink::WebCryptoResult& result,
  242. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  243. : BaseState(result, std::move(task_runner)),
  244. format(format),
  245. key(key),
  246. wrapping_key(wrapping_key),
  247. wrap_algorithm(wrap_algorithm) {}
  248. const blink::WebCryptoKeyFormat format;
  249. const blink::WebCryptoKey key;
  250. const blink::WebCryptoKey wrapping_key;
  251. const blink::WebCryptoAlgorithm wrap_algorithm;
  252. std::vector<uint8_t> buffer;
  253. };
  254. struct UnwrapKeyState : public BaseState {
  255. UnwrapKeyState(blink::WebCryptoKeyFormat format,
  256. blink::WebVector<unsigned char> wrapped_key,
  257. const blink::WebCryptoKey& wrapping_key,
  258. const blink::WebCryptoAlgorithm& unwrap_algorithm,
  259. const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
  260. bool extractable,
  261. blink::WebCryptoKeyUsageMask usages,
  262. const blink::WebCryptoResult& result,
  263. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  264. : BaseState(result, std::move(task_runner)),
  265. format(format),
  266. wrapped_key(std::move(wrapped_key)),
  267. wrapping_key(wrapping_key),
  268. unwrap_algorithm(unwrap_algorithm),
  269. unwrapped_key_algorithm(unwrapped_key_algorithm),
  270. extractable(extractable),
  271. usages(usages) {}
  272. const blink::WebCryptoKeyFormat format;
  273. blink::WebVector<unsigned char> wrapped_key;
  274. const blink::WebCryptoKey wrapping_key;
  275. const blink::WebCryptoAlgorithm unwrap_algorithm;
  276. const blink::WebCryptoAlgorithm unwrapped_key_algorithm;
  277. const bool extractable;
  278. const blink::WebCryptoKeyUsageMask usages;
  279. blink::WebCryptoKey unwrapped_key;
  280. };
  281. struct DeriveBitsState : public BaseState {
  282. DeriveBitsState(const blink::WebCryptoAlgorithm& algorithm,
  283. const blink::WebCryptoKey& base_key,
  284. unsigned int length_bits,
  285. const blink::WebCryptoResult& result,
  286. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  287. : BaseState(result, std::move(task_runner)),
  288. algorithm(algorithm),
  289. base_key(base_key),
  290. length_bits(length_bits) {}
  291. const blink::WebCryptoAlgorithm algorithm;
  292. const blink::WebCryptoKey base_key;
  293. const unsigned int length_bits;
  294. std::vector<uint8_t> derived_bytes;
  295. };
  296. struct DeriveKeyState : public BaseState {
  297. DeriveKeyState(const blink::WebCryptoAlgorithm& algorithm,
  298. const blink::WebCryptoKey& base_key,
  299. const blink::WebCryptoAlgorithm& import_algorithm,
  300. const blink::WebCryptoAlgorithm& key_length_algorithm,
  301. bool extractable,
  302. blink::WebCryptoKeyUsageMask usages,
  303. const blink::WebCryptoResult& result,
  304. scoped_refptr<base::SingleThreadTaskRunner> task_runner)
  305. : BaseState(result, std::move(task_runner)),
  306. algorithm(algorithm),
  307. base_key(base_key),
  308. import_algorithm(import_algorithm),
  309. key_length_algorithm(key_length_algorithm),
  310. extractable(extractable),
  311. usages(usages) {}
  312. const blink::WebCryptoAlgorithm algorithm;
  313. const blink::WebCryptoKey base_key;
  314. const blink::WebCryptoAlgorithm import_algorithm;
  315. const blink::WebCryptoAlgorithm key_length_algorithm;
  316. bool extractable;
  317. blink::WebCryptoKeyUsageMask usages;
  318. blink::WebCryptoKey derived_key;
  319. };
  320. // --------------------------------------------------------------------
  321. // Wrapper functions
  322. // --------------------------------------------------------------------
  323. //
  324. // * The methods named Do*() run on the crypto thread.
  325. // * The methods named Do*Reply() run on the target Blink thread
  326. void DoEncryptReply(std::unique_ptr<EncryptState> state) {
  327. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
  328. "DoEncryptReply");
  329. CompleteWithBufferOrError(state->status, state->buffer, &state->result);
  330. }
  331. void DoEncrypt(std::unique_ptr<EncryptState> passed_state) {
  332. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoEncrypt");
  333. EncryptState* state = passed_state.get();
  334. if (state->cancelled())
  335. return;
  336. state->status = webcrypto::Encrypt(state->algorithm, state->key, state->data,
  337. &state->buffer);
  338. state->origin_thread->PostTask(
  339. FROM_HERE, base::BindOnce(DoEncryptReply, std::move(passed_state)));
  340. }
  341. void DoDecryptReply(std::unique_ptr<DecryptState> state) {
  342. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
  343. "DoDecryptReply");
  344. CompleteWithBufferOrError(state->status, state->buffer, &state->result);
  345. }
  346. void DoDecrypt(std::unique_ptr<DecryptState> passed_state) {
  347. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoDecrypt");
  348. DecryptState* state = passed_state.get();
  349. if (state->cancelled())
  350. return;
  351. state->status = webcrypto::Decrypt(state->algorithm, state->key, state->data,
  352. &state->buffer);
  353. state->origin_thread->PostTask(
  354. FROM_HERE, base::BindOnce(DoDecryptReply, std::move(passed_state)));
  355. }
  356. void DoDigestReply(std::unique_ptr<DigestState> state) {
  357. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoDigestReply");
  358. CompleteWithBufferOrError(state->status, state->buffer, &state->result);
  359. }
  360. void DoDigest(std::unique_ptr<DigestState> passed_state) {
  361. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoDigest");
  362. DigestState* state = passed_state.get();
  363. if (state->cancelled())
  364. return;
  365. state->status =
  366. webcrypto::Digest(state->algorithm, state->data, &state->buffer);
  367. state->origin_thread->PostTask(
  368. FROM_HERE, base::BindOnce(DoDigestReply, std::move(passed_state)));
  369. }
  370. void DoGenerateKeyReply(std::unique_ptr<GenerateKeyState> state) {
  371. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
  372. "DoGenerateKeyReply");
  373. if (state->status.IsError()) {
  374. CompleteWithError(state->status, &state->result);
  375. } else {
  376. state->generate_key_result.Complete(&state->result);
  377. }
  378. }
  379. void DoGenerateKey(std::unique_ptr<GenerateKeyState> passed_state) {
  380. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoGenerateKey");
  381. GenerateKeyState* state = passed_state.get();
  382. if (state->cancelled())
  383. return;
  384. state->status =
  385. webcrypto::GenerateKey(state->algorithm, state->extractable,
  386. state->usages, &state->generate_key_result);
  387. state->origin_thread->PostTask(
  388. FROM_HERE, base::BindOnce(DoGenerateKeyReply, std::move(passed_state)));
  389. }
  390. void DoImportKeyReply(std::unique_ptr<ImportKeyState> state) {
  391. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
  392. "DoImportKeyReply");
  393. CompleteWithKeyOrError(state->status, state->key, &state->result);
  394. }
  395. void DoImportKey(std::unique_ptr<ImportKeyState> passed_state) {
  396. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoImportKey");
  397. ImportKeyState* state = passed_state.get();
  398. if (state->cancelled())
  399. return;
  400. state->status =
  401. webcrypto::ImportKey(state->format, state->key_data, state->algorithm,
  402. state->extractable, state->usages, &state->key);
  403. if (state->status.IsSuccess()) {
  404. DCHECK(state->key.Handle());
  405. DCHECK(!state->key.Algorithm().IsNull());
  406. DCHECK_EQ(state->extractable, state->key.Extractable());
  407. }
  408. state->origin_thread->PostTask(
  409. FROM_HERE, base::BindOnce(DoImportKeyReply, std::move(passed_state)));
  410. }
  411. void DoExportKeyReply(std::unique_ptr<ExportKeyState> state) {
  412. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
  413. "DoExportKeyReply");
  414. if (state->format != blink::kWebCryptoKeyFormatJwk) {
  415. CompleteWithBufferOrError(state->status, state->buffer, &state->result);
  416. return;
  417. }
  418. if (state->status.IsError()) {
  419. CompleteWithError(state->status, &state->result);
  420. } else {
  421. state->result.CompleteWithJson(
  422. reinterpret_cast<const char*>(state->buffer.data()),
  423. static_cast<unsigned int>(state->buffer.size()));
  424. }
  425. }
  426. void DoExportKey(std::unique_ptr<ExportKeyState> passed_state) {
  427. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoExportKey");
  428. ExportKeyState* state = passed_state.get();
  429. if (state->cancelled())
  430. return;
  431. state->status =
  432. webcrypto::ExportKey(state->format, state->key, &state->buffer);
  433. state->origin_thread->PostTask(
  434. FROM_HERE, base::BindOnce(DoExportKeyReply, std::move(passed_state)));
  435. }
  436. void DoSignReply(std::unique_ptr<SignState> state) {
  437. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoSignReply");
  438. CompleteWithBufferOrError(state->status, state->buffer, &state->result);
  439. }
  440. void DoSign(std::unique_ptr<SignState> passed_state) {
  441. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoSign");
  442. SignState* state = passed_state.get();
  443. if (state->cancelled())
  444. return;
  445. state->status = webcrypto::Sign(state->algorithm, state->key, state->data,
  446. &state->buffer);
  447. state->origin_thread->PostTask(
  448. FROM_HERE, base::BindOnce(DoSignReply, std::move(passed_state)));
  449. }
  450. void DoVerifyReply(std::unique_ptr<VerifySignatureState> state) {
  451. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoVerifyReply");
  452. if (state->status.IsError()) {
  453. CompleteWithError(state->status, &state->result);
  454. } else {
  455. state->result.CompleteWithBoolean(state->verify_result);
  456. }
  457. }
  458. void DoVerify(std::unique_ptr<VerifySignatureState> passed_state) {
  459. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoVerify");
  460. VerifySignatureState* state = passed_state.get();
  461. if (state->cancelled())
  462. return;
  463. state->status =
  464. webcrypto::Verify(state->algorithm, state->key, state->signature,
  465. state->data, &state->verify_result);
  466. state->origin_thread->PostTask(
  467. FROM_HERE, base::BindOnce(DoVerifyReply, std::move(passed_state)));
  468. }
  469. void DoWrapKeyReply(std::unique_ptr<WrapKeyState> state) {
  470. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
  471. "DoWrapKeyReply");
  472. CompleteWithBufferOrError(state->status, state->buffer, &state->result);
  473. }
  474. void DoWrapKey(std::unique_ptr<WrapKeyState> passed_state) {
  475. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoWrapKey");
  476. WrapKeyState* state = passed_state.get();
  477. if (state->cancelled())
  478. return;
  479. state->status =
  480. webcrypto::WrapKey(state->format, state->key, state->wrapping_key,
  481. state->wrap_algorithm, &state->buffer);
  482. state->origin_thread->PostTask(
  483. FROM_HERE, base::BindOnce(DoWrapKeyReply, std::move(passed_state)));
  484. }
  485. void DoUnwrapKeyReply(std::unique_ptr<UnwrapKeyState> state) {
  486. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
  487. "DoUnwrapKeyReply");
  488. CompleteWithKeyOrError(state->status, state->unwrapped_key, &state->result);
  489. }
  490. void DoUnwrapKey(std::unique_ptr<UnwrapKeyState> passed_state) {
  491. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoUnwrapKey");
  492. UnwrapKeyState* state = passed_state.get();
  493. if (state->cancelled())
  494. return;
  495. state->status = webcrypto::UnwrapKey(
  496. state->format, state->wrapped_key, state->wrapping_key,
  497. state->unwrap_algorithm, state->unwrapped_key_algorithm,
  498. state->extractable, state->usages, &state->unwrapped_key);
  499. state->origin_thread->PostTask(
  500. FROM_HERE, base::BindOnce(DoUnwrapKeyReply, std::move(passed_state)));
  501. }
  502. void DoDeriveBitsReply(std::unique_ptr<DeriveBitsState> state) {
  503. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
  504. "DoDeriveBitsReply");
  505. CompleteWithBufferOrError(state->status, state->derived_bytes,
  506. &state->result);
  507. }
  508. void DoDeriveBits(std::unique_ptr<DeriveBitsState> passed_state) {
  509. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoDeriveBits");
  510. DeriveBitsState* state = passed_state.get();
  511. if (state->cancelled())
  512. return;
  513. state->status =
  514. webcrypto::DeriveBits(state->algorithm, state->base_key,
  515. state->length_bits, &state->derived_bytes);
  516. state->origin_thread->PostTask(
  517. FROM_HERE, base::BindOnce(DoDeriveBitsReply, std::move(passed_state)));
  518. }
  519. void DoDeriveKeyReply(std::unique_ptr<DeriveKeyState> state) {
  520. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
  521. "DoDeriveKeyReply");
  522. CompleteWithKeyOrError(state->status, state->derived_key, &state->result);
  523. }
  524. void DoDeriveKey(std::unique_ptr<DeriveKeyState> passed_state) {
  525. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "DoDeriveKey");
  526. DeriveKeyState* state = passed_state.get();
  527. if (state->cancelled())
  528. return;
  529. state->status = webcrypto::DeriveKey(
  530. state->algorithm, state->base_key, state->import_algorithm,
  531. state->key_length_algorithm, state->extractable, state->usages,
  532. &state->derived_key);
  533. state->origin_thread->PostTask(
  534. FROM_HERE, base::BindOnce(DoDeriveKeyReply, std::move(passed_state)));
  535. }
  536. } // namespace
  537. WebCryptoImpl::WebCryptoImpl() {
  538. }
  539. WebCryptoImpl::~WebCryptoImpl() {
  540. }
  541. void WebCryptoImpl::Encrypt(
  542. const blink::WebCryptoAlgorithm& algorithm,
  543. const blink::WebCryptoKey& key,
  544. blink::WebVector<unsigned char> data,
  545. blink::WebCryptoResult result,
  546. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  547. DCHECK(!algorithm.IsNull());
  548. if (result.Cancelled())
  549. return;
  550. std::unique_ptr<EncryptState> state(new EncryptState(
  551. algorithm, key, std::move(data), result, std::move(task_runner)));
  552. if (!CryptoThreadPool::PostTask(
  553. FROM_HERE, base::BindOnce(DoEncrypt, std::move(state)))) {
  554. CompleteWithThreadPoolError(&result);
  555. }
  556. }
  557. void WebCryptoImpl::Decrypt(
  558. const blink::WebCryptoAlgorithm& algorithm,
  559. const blink::WebCryptoKey& key,
  560. blink::WebVector<unsigned char> data,
  561. blink::WebCryptoResult result,
  562. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  563. DCHECK(!algorithm.IsNull());
  564. if (result.Cancelled())
  565. return;
  566. std::unique_ptr<DecryptState> state(new DecryptState(
  567. algorithm, key, std::move(data), result, std::move(task_runner)));
  568. if (!CryptoThreadPool::PostTask(
  569. FROM_HERE, base::BindOnce(DoDecrypt, std::move(state)))) {
  570. CompleteWithThreadPoolError(&result);
  571. }
  572. }
  573. void WebCryptoImpl::Digest(
  574. const blink::WebCryptoAlgorithm& algorithm,
  575. blink::WebVector<unsigned char> data,
  576. blink::WebCryptoResult result,
  577. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  578. DCHECK(!algorithm.IsNull());
  579. if (result.Cancelled())
  580. return;
  581. std::unique_ptr<DigestState> state(
  582. new DigestState(algorithm, blink::WebCryptoKey::CreateNull(),
  583. std::move(data), result, std::move(task_runner)));
  584. if (!CryptoThreadPool::PostTask(FROM_HERE,
  585. base::BindOnce(DoDigest, std::move(state)))) {
  586. CompleteWithThreadPoolError(&result);
  587. }
  588. }
  589. void WebCryptoImpl::GenerateKey(
  590. const blink::WebCryptoAlgorithm& algorithm,
  591. bool extractable,
  592. blink::WebCryptoKeyUsageMask usages,
  593. blink::WebCryptoResult result,
  594. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  595. DCHECK(!algorithm.IsNull());
  596. if (result.Cancelled())
  597. return;
  598. std::unique_ptr<GenerateKeyState> state(new GenerateKeyState(
  599. algorithm, extractable, usages, result, std::move(task_runner)));
  600. if (!CryptoThreadPool::PostTask(
  601. FROM_HERE, base::BindOnce(DoGenerateKey, std::move(state)))) {
  602. CompleteWithThreadPoolError(&result);
  603. }
  604. }
  605. void WebCryptoImpl::ImportKey(
  606. blink::WebCryptoKeyFormat format,
  607. blink::WebVector<unsigned char> key_data,
  608. const blink::WebCryptoAlgorithm& algorithm,
  609. bool extractable,
  610. blink::WebCryptoKeyUsageMask usages,
  611. blink::WebCryptoResult result,
  612. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  613. if (result.Cancelled())
  614. return;
  615. std::unique_ptr<ImportKeyState> state(
  616. new ImportKeyState(format, std::move(key_data), algorithm, extractable,
  617. usages, result, std::move(task_runner)));
  618. if (!CryptoThreadPool::PostTask(
  619. FROM_HERE, base::BindOnce(DoImportKey, std::move(state)))) {
  620. CompleteWithThreadPoolError(&result);
  621. }
  622. }
  623. void WebCryptoImpl::ExportKey(
  624. blink::WebCryptoKeyFormat format,
  625. const blink::WebCryptoKey& key,
  626. blink::WebCryptoResult result,
  627. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  628. if (result.Cancelled())
  629. return;
  630. std::unique_ptr<ExportKeyState> state(
  631. new ExportKeyState(format, key, result, std::move(task_runner)));
  632. if (!CryptoThreadPool::PostTask(
  633. FROM_HERE, base::BindOnce(DoExportKey, std::move(state)))) {
  634. CompleteWithThreadPoolError(&result);
  635. }
  636. }
  637. void WebCryptoImpl::Sign(
  638. const blink::WebCryptoAlgorithm& algorithm,
  639. const blink::WebCryptoKey& key,
  640. blink::WebVector<unsigned char> data,
  641. blink::WebCryptoResult result,
  642. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  643. if (result.Cancelled())
  644. return;
  645. std::unique_ptr<SignState> state(new SignState(
  646. algorithm, key, std::move(data), result, std::move(task_runner)));
  647. if (!CryptoThreadPool::PostTask(FROM_HERE,
  648. base::BindOnce(DoSign, std::move(state)))) {
  649. CompleteWithThreadPoolError(&result);
  650. }
  651. }
  652. void WebCryptoImpl::VerifySignature(
  653. const blink::WebCryptoAlgorithm& algorithm,
  654. const blink::WebCryptoKey& key,
  655. blink::WebVector<unsigned char> signature,
  656. blink::WebVector<unsigned char> data,
  657. blink::WebCryptoResult result,
  658. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  659. if (result.Cancelled())
  660. return;
  661. std::unique_ptr<VerifySignatureState> state(new VerifySignatureState(
  662. algorithm, key, std::move(signature), std::move(data), result,
  663. std::move(task_runner)));
  664. if (!CryptoThreadPool::PostTask(FROM_HERE,
  665. base::BindOnce(DoVerify, std::move(state)))) {
  666. CompleteWithThreadPoolError(&result);
  667. }
  668. }
  669. void WebCryptoImpl::WrapKey(
  670. blink::WebCryptoKeyFormat format,
  671. const blink::WebCryptoKey& key,
  672. const blink::WebCryptoKey& wrapping_key,
  673. const blink::WebCryptoAlgorithm& wrap_algorithm,
  674. blink::WebCryptoResult result,
  675. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  676. if (result.Cancelled())
  677. return;
  678. std::unique_ptr<WrapKeyState> state(
  679. new WrapKeyState(format, key, wrapping_key, wrap_algorithm, result,
  680. std::move(task_runner)));
  681. if (!CryptoThreadPool::PostTask(
  682. FROM_HERE, base::BindOnce(DoWrapKey, std::move(state)))) {
  683. CompleteWithThreadPoolError(&result);
  684. }
  685. }
  686. void WebCryptoImpl::UnwrapKey(
  687. blink::WebCryptoKeyFormat format,
  688. blink::WebVector<unsigned char> wrapped_key,
  689. const blink::WebCryptoKey& wrapping_key,
  690. const blink::WebCryptoAlgorithm& unwrap_algorithm,
  691. const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
  692. bool extractable,
  693. blink::WebCryptoKeyUsageMask usages,
  694. blink::WebCryptoResult result,
  695. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  696. if (result.Cancelled())
  697. return;
  698. std::unique_ptr<UnwrapKeyState> state(
  699. new UnwrapKeyState(format, std::move(wrapped_key), wrapping_key,
  700. unwrap_algorithm, unwrapped_key_algorithm, extractable,
  701. usages, result, std::move(task_runner)));
  702. if (!CryptoThreadPool::PostTask(
  703. FROM_HERE, base::BindOnce(DoUnwrapKey, std::move(state)))) {
  704. CompleteWithThreadPoolError(&result);
  705. }
  706. }
  707. void WebCryptoImpl::DeriveBits(
  708. const blink::WebCryptoAlgorithm& algorithm,
  709. const blink::WebCryptoKey& base_key,
  710. unsigned int length_bits,
  711. blink::WebCryptoResult result,
  712. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  713. if (result.Cancelled())
  714. return;
  715. std::unique_ptr<DeriveBitsState> state(new DeriveBitsState(
  716. algorithm, base_key, length_bits, result, std::move(task_runner)));
  717. if (!CryptoThreadPool::PostTask(
  718. FROM_HERE, base::BindOnce(DoDeriveBits, std::move(state)))) {
  719. CompleteWithThreadPoolError(&result);
  720. }
  721. }
  722. void WebCryptoImpl::DeriveKey(
  723. const blink::WebCryptoAlgorithm& algorithm,
  724. const blink::WebCryptoKey& base_key,
  725. const blink::WebCryptoAlgorithm& import_algorithm,
  726. const blink::WebCryptoAlgorithm& key_length_algorithm,
  727. bool extractable,
  728. blink::WebCryptoKeyUsageMask usages,
  729. blink::WebCryptoResult result,
  730. scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  731. if (result.Cancelled())
  732. return;
  733. std::unique_ptr<DeriveKeyState> state(new DeriveKeyState(
  734. algorithm, base_key, import_algorithm, key_length_algorithm, extractable,
  735. usages, result, std::move(task_runner)));
  736. if (!CryptoThreadPool::PostTask(
  737. FROM_HERE, base::BindOnce(DoDeriveKey, std::move(state)))) {
  738. CompleteWithThreadPoolError(&result);
  739. }
  740. }
  741. bool WebCryptoImpl::DeserializeKeyForClone(
  742. const blink::WebCryptoKeyAlgorithm& algorithm,
  743. blink::WebCryptoKeyType type,
  744. bool extractable,
  745. blink::WebCryptoKeyUsageMask usages,
  746. const unsigned char* key_data,
  747. unsigned key_data_size,
  748. blink::WebCryptoKey& key) {
  749. return webcrypto::DeserializeKeyForClone(
  750. algorithm, type, extractable, usages,
  751. base::make_span(key_data, key_data_size), &key);
  752. }
  753. bool WebCryptoImpl::SerializeKeyForClone(
  754. const blink::WebCryptoKey& key,
  755. blink::WebVector<unsigned char>& key_data) {
  756. return webcrypto::SerializeKeyForClone(key, &key_data);
  757. }
  758. } // namespace webcrypto