OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/webcrypto/webcrypto_impl.h" | 5 #include "components/webcrypto/webcrypto_impl.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 using webcrypto::Status; | 30 using webcrypto::Status; |
31 | 31 |
32 namespace { | 32 namespace { |
33 | 33 |
34 // --------------------- | 34 // --------------------- |
35 // Threading | 35 // Threading |
36 // --------------------- | 36 // --------------------- |
37 // | 37 // |
38 // WebCrypto operations can be slow. For instance generating an RSA key can | 38 // WebCrypto operations can be slow. For instance generating an RSA key can |
39 // seconds. | 39 // take seconds. |
40 // | |
41 // Moreover the underlying crypto libraries are not threadsafe when operating | |
42 // on the same key. | |
43 // | 40 // |
44 // The strategy used here is to run a sequenced worker pool for all WebCrypto | 41 // The strategy used here is to run a sequenced worker pool for all WebCrypto |
45 // operations (except structured cloning). This same pool is also used by | 42 // operations (except structured cloning). This same pool is also used by |
46 // requests started from Blink Web Workers. | 43 // requests started from Blink Web Workers. |
47 // | 44 // |
48 // A few notes to keep in mind: | 45 // A few notes to keep in mind: |
49 // | 46 // |
50 // * PostTaskAndReply() cannot be used for two reasons: | 47 // * PostTaskAndReply() is not used because of how it handles failures -- it |
| 48 // leaks the callback when failing to post back to the origin thread. |
51 // | 49 // |
52 // (1) Blink web worker threads do not have an associated message loop so | 50 // This is a problem since WebCrypto may be called from WebWorker threads, |
53 // construction of the reply callback will crash. | 51 // which may be aborted at any time. Leaking would be undesirable, and |
54 // | 52 // reachable in practice. |
55 // (2) PostTaskAndReply() handles failure posting the reply by leaking the | |
56 // callback, rather than destroying it. In the case of Web Workers this | |
57 // condition is reachable via normal execution, since Web Workers can | |
58 // be stopped before the WebCrypto operation has finished. A policy of | |
59 // leaking would therefore be problematic. | |
60 // | 53 // |
61 // * blink::WebArrayBuffer is NOT threadsafe, and should therefore be allocated | 54 // * blink::WebArrayBuffer is NOT threadsafe, and should therefore be allocated |
62 // on the target Blink thread. | 55 // only on the target Blink thread. |
63 // | 56 // |
64 // TODO(eroman): Is there any way around this? Copying the result between | 57 // TODO(eroman): Is there any way around this? Copying the result between |
65 // threads is silly. | 58 // threads is silly. |
66 // | 59 // |
67 // * WebCryptoAlgorithm and WebCryptoKey are threadsafe (however the key's | 60 // * WebCryptoAlgorithm and WebCryptoKey are threadsafe, by virtue of being |
68 // handle(), which wraps an OpenSSL type, may not be and should only be | 61 // immutable. Internally asymmetric WebCryptoKeys wrap BoringSSL's EVP_PKEY. |
69 // used from the webcrypto thread). | 62 // These are safe to use for BoringSSL operations across threads, provided |
| 63 // the internals of the EVP_PKEY are not mutated (they never should be |
| 64 // following ImportKey()). |
70 // | 65 // |
71 // * blink::WebCryptoResult is not threadsafe and should only be operated on | 66 // * blink::WebCryptoResult is not threadsafe and should only be operated on |
72 // the target Blink thread. HOWEVER, it is safe to delete it from any thread. | 67 // the target Blink thread. HOWEVER, it is safe to delete it from any thread. |
73 // This can happen if by the time the operation has completed in the crypto | 68 // This can happen if by the time the operation has completed in the crypto |
74 // worker pool, the Blink worker thread that initiated the request is gone. | 69 // worker pool, the Blink worker thread that initiated the request is gone. |
75 // Posting back to the origin thread will fail, and the WebCryptoResult will | 70 // Posting back to the origin thread will fail, and the WebCryptoResult will |
76 // be deleted while running in the crypto worker pool. | 71 // be deleted while running in the crypto worker pool. |
77 class CryptoThreadPool { | 72 class CryptoThreadPool { |
78 public: | 73 public: |
79 CryptoThreadPool() | 74 CryptoThreadPool() |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 webcrypto::CryptoData(key_data, key_data_size), &key); | 781 webcrypto::CryptoData(key_data, key_data_size), &key); |
787 } | 782 } |
788 | 783 |
789 bool WebCryptoImpl::serializeKeyForClone( | 784 bool WebCryptoImpl::serializeKeyForClone( |
790 const blink::WebCryptoKey& key, | 785 const blink::WebCryptoKey& key, |
791 blink::WebVector<unsigned char>& key_data) { | 786 blink::WebVector<unsigned char>& key_data) { |
792 return webcrypto::SerializeKeyForClone(key, &key_data); | 787 return webcrypto::SerializeKeyForClone(key, &key_data); |
793 } | 788 } |
794 | 789 |
795 } // namespace webcrypto | 790 } // namespace webcrypto |
OLD | NEW |