| 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 |