diff --git a/components/script/dom/subtlecrypto.rs b/components/script/dom/subtlecrypto.rs index cbf624758cd..116fa55c24d 100644 --- a/components/script/dom/subtlecrypto.rs +++ b/components/script/dom/subtlecrypto.rs @@ -132,6 +132,32 @@ impl SubtleCrypto { pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot { reflect_dom_object(Box::new(SubtleCrypto::new_inherited()), global, can_gc) } + + /// Queue a global task on the crypto task source, given realm's global object, to resolve + /// promise with a CryptoKey. + fn resolve_promise_with_key(&self, promise: Rc, key: DomRoot) { + let trusted_key = Trusted::new(&*key); + let trusted_promise = TrustedPromise::new(promise); + self.global().task_manager().crypto_task_source().queue( + task!(generate_key_result: move || { + let key = trusted_key.root(); + let promise = trusted_promise.root(); + promise.resolve_native(&key, CanGc::note()); + }), + ); + } + + /// Queue a global task on the crypto task source, given realm's global object, to reject + /// promise with an error. + fn reject_promise_with_error(&self, promise: Rc, error: Error) { + let trusted_promise = TrustedPromise::new(promise); + self.global().task_manager().crypto_task_source().queue( + task!(generate_key_result: move || { + let promise = trusted_promise.root(); + promise.reject_error(error, CanGc::note()); + }), + ); + } } impl SubtleCryptoMethods for SubtleCrypto { @@ -556,17 +582,16 @@ impl SubtleCryptoMethods for SubtleCrypto { }, }; - // TODO: Step 10. Queue a global task on the crypto task source, given realm's - // global object, to perform the remaining steps. - + // Step 10. Queue a global task on the crypto task source, given realm's global + // object, to perform the remaining steps. // Step 11. Let result be the result of converting result to an ECMAScript Object // in realm, as defined by [WebIDL]. // Step 12. Resolve promise with result. - // TODO: Implement CryptoKeyPair case match key { - CryptoKeyOrCryptoKeyPair::CryptoKey(crypto_key) => - promise.resolve_native(&crypto_key, CanGc::note()), - }; + CryptoKeyOrCryptoKeyPair::CryptoKey(key) => { + subtle.resolve_promise_with_key(promise, key); + }, + } })); promise @@ -876,10 +901,9 @@ impl SubtleCryptoMethods for SubtleCrypto { let subtle = this.root(); let promise = trusted_promise.root(); - // TODO: Step 8. If the following steps or referenced procedures say to throw an - // error, queue a global task on the crypto task source, given realm's global - // object, to reject promise with the returned error; and then terminate the - // algorithm. + // Step 8. If the following steps or referenced procedures say to throw an error, + // queue a global task on the crypto task source, given realm's global object, to + // reject promise with the returned error; and then terminate the algorithm. // Step 9. Let result be the CryptoKey object that results from performing the // import key operation specified by normalizedAlgorithm using keyData, algorithm, @@ -894,7 +918,7 @@ impl SubtleCryptoMethods for SubtleCrypto { ) { Ok(key) => key, Err(error) => { - promise.reject_error(error, CanGc::note()); + subtle.reject_promise_with_error(promise, error); return; }, }; @@ -902,7 +926,7 @@ impl SubtleCryptoMethods for SubtleCrypto { // Step 10. If the [[type]] internal slot of result is "secret" or "private" and // usages is empty, then throw a SyntaxError. if matches!(result.Type(), KeyType::Secret | KeyType::Private) && key_usages.is_empty() { - promise.reject_error(Error::Syntax(None), CanGc::note()); + subtle.reject_promise_with_error(promise, Error::Syntax(None)); return; } @@ -912,13 +936,12 @@ impl SubtleCryptoMethods for SubtleCrypto { // Step 12. Set the [[usages]] internal slot of result to the normalized value of usages. result.set_usages(&key_usages); - // TODO: Step 13. Queue a global task on the crypto task source, given realm's - // global object, to perform the remaining steps. - + // Step 13. Queue a global task on the crypto task source, given realm's global + // object, to perform the remaining steps. // Step 14. Let result be the result of converting result to an ECMAScript Object // in realm, as defined by [WebIDL]. // Step 15. Resolve promise with result. - promise.resolve_native(&result, CanGc::note()); + subtle.resolve_promise_with_key(promise, result); })); promise diff --git a/components/script/task_manager.rs b/components/script/task_manager.rs index b4da5078920..9524f850968 100644 --- a/components/script/task_manager.rs +++ b/components/script/task_manager.rs @@ -135,6 +135,7 @@ impl TaskManager { task_source_functions!(self, bitmap_task_source, Bitmap); task_source_functions!(self, canvas_blob_task_source, Canvas); task_source_functions!(self, clipboard_task_source, Clipboard); + task_source_functions!(self, crypto_task_source, Crypto); task_source_functions!(self, database_access_task_source, DatabaseAccess); task_source_functions!(self, dom_manipulation_task_source, DOMManipulation); task_source_functions!(self, file_reading_task_source, FileReading); diff --git a/components/script/task_source.rs b/components/script/task_source.rs index 23999c70ade..c887f73cc87 100644 --- a/components/script/task_source.rs +++ b/components/script/task_source.rs @@ -26,6 +26,8 @@ pub(crate) enum TaskSourceName { Bitmap, Canvas, Clipboard, + /// + Crypto, DatabaseAccess, DOMManipulation, FileReading, @@ -56,6 +58,7 @@ impl From for ScriptThreadEventCategory { TaskSourceName::Bitmap => ScriptThreadEventCategory::ScriptEvent, TaskSourceName::Canvas => ScriptThreadEventCategory::ScriptEvent, TaskSourceName::Clipboard => ScriptThreadEventCategory::ScriptEvent, + TaskSourceName::Crypto => ScriptThreadEventCategory::ScriptEvent, TaskSourceName::DatabaseAccess => ScriptThreadEventCategory::ScriptEvent, TaskSourceName::DOMManipulation => ScriptThreadEventCategory::ScriptEvent, TaskSourceName::FileReading => ScriptThreadEventCategory::FileRead, diff --git a/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js.ini b/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js.ini index e45a3994de6..70ed12b1b45 100644 --- a/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js.ini +++ b/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js.ini @@ -50,6 +50,7 @@ [cfrg_curves_bits_curve25519.https.any.worker.html] + expected: ERROR [X25519 key derivation checks for all-zero value result with a key of order 0] expected: FAIL diff --git a/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js.ini b/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js.ini index 5d052adc934..e6559caa3d9 100644 --- a/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js.ini +++ b/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js.ini @@ -47,6 +47,7 @@ [cfrg_curves_bits_curve448.tentative.https.any.worker.html] + expected: ERROR [X448 key derivation checks for all-zero value result with a key of order 0] expected: FAIL diff --git a/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js.ini b/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js.ini index d287e19db6d..96387e197c5 100644 --- a/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js.ini +++ b/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js.ini @@ -1,4 +1,5 @@ [cfrg_curves_keys_curve25519.https.any.worker.html] + expected: ERROR [X25519 deriveBits checks for all-zero value result with a key of order 0] expected: FAIL diff --git a/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js.ini b/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js.ini index 27926555f86..3dcbcdfb8e4 100644 --- a/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js.ini +++ b/tests/wpt/meta/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js.ini @@ -1,4 +1,5 @@ [cfrg_curves_keys_curve448.tentative.https.any.worker.html] + expected: ERROR [X448 deriveBits checks for all-zero value result with a key of order 0] expected: FAIL