diff --git a/components/script/dom/cryptokey.rs b/components/script/dom/cryptokey.rs index 6d9a6c562be..498199c586e 100644 --- a/components/script/dom/cryptokey.rs +++ b/components/script/dom/cryptokey.rs @@ -20,6 +20,11 @@ use crate::dom::bindings::str::DOMString; use crate::dom::globalscope::GlobalScope; use crate::script_runtime::{CanGc, JSContext}; +pub(crate) enum CryptoKeyOrCryptoKeyPair { + CryptoKey(DomRoot), + // TODO: CryptoKeyPair(CryptoKeyPair), +} + /// The underlying cryptographic data this key represents #[allow(dead_code)] #[derive(MallocSizeOf)] diff --git a/components/script/dom/subtlecrypto.rs b/components/script/dom/subtlecrypto.rs index 12753a77c62..cbf624758cd 100644 --- a/components/script/dom/subtlecrypto.rs +++ b/components/script/dom/subtlecrypto.rs @@ -46,7 +46,7 @@ use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::{DOMString, serialize_jsval_to_json_utf8}; use crate::dom::bindings::trace::RootedTraceableBox; -use crate::dom::cryptokey::{CryptoKey, Handle}; +use crate::dom::cryptokey::{CryptoKey, CryptoKeyOrCryptoKeyPair, Handle}; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::realms::InRealm; @@ -524,12 +524,49 @@ impl SubtleCryptoMethods for SubtleCrypto { .queue(task!(generate_key: move || { let subtle = this.root(); let promise = trusted_promise.root(); - let key = normalized_algorithm.generate_key(&subtle, key_usages, extractable, CanGc::note()); + // Step 8. Let result be the result of performing the generate key operation + // specified by normalizedAlgorithm using algorithm, extractable and usages. + let key = match normalized_algorithm + .generate_key(&subtle, key_usages, extractable, CanGc::note()) + { + Ok(key) => key, + Err(error) => { + promise.reject_error(error, CanGc::note()); + return; + } + }; + + // Step 9. + // If result is a CryptoKey object: + // If the [[type]] internal slot of result is "secret" or "private" and usages + // is empty, then throw a SyntaxError. + // If result is a CryptoKeyPair object: + // If the [[usages]] internal slot of the privateKey attribute of result is the + // empty sequence, then throw a SyntaxError. + // TODO: Implement CryptoKeyPair case + match &key { + CryptoKeyOrCryptoKeyPair::CryptoKey(crpyto_key) => { + if matches!(crpyto_key.Type(), KeyType::Secret | KeyType::Private) + && crpyto_key.usages().is_empty() + { + promise.reject_error(Error::Syntax(None), CanGc::note()); + return; + } + }, + }; + + // TODO: 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 { - Ok(key) => promise.resolve_native(&key, CanGc::note()), - Err(e) => promise.reject_error(e, CanGc::note()), - } + CryptoKeyOrCryptoKeyPair::CryptoKey(crypto_key) => + promise.resolve_native(&crypto_key, CanGc::note()), + }; })); promise @@ -3531,11 +3568,21 @@ impl KeyGenerationAlgorithm { usages: Vec, extractable: bool, can_gc: CanGc, - ) -> Result, Error> { - match self { - Self::Aes(params) => subtle.generate_key_aes(usages, params, extractable, can_gc), - Self::Hmac(params) => subtle.generate_key_hmac(usages, params, extractable, can_gc), - } + ) -> Result { + let key_or_key_pair = + match self { + Self::Aes(params) => CryptoKeyOrCryptoKeyPair::CryptoKey(subtle.generate_key_aes( + usages, + params, + extractable, + can_gc, + )?), + Self::Hmac(params) => CryptoKeyOrCryptoKeyPair::CryptoKey( + subtle.generate_key_hmac(usages, params, extractable, can_gc)?, + ), + }; + + Ok(key_or_key_pair) } } diff --git a/components/script_bindings/webidls/CryptoKey.webidl b/components/script_bindings/webidls/CryptoKey.webidl index 3540a2e9db7..09dc13fb88f 100644 --- a/components/script_bindings/webidls/CryptoKey.webidl +++ b/components/script_bindings/webidls/CryptoKey.webidl @@ -15,3 +15,10 @@ interface CryptoKey { readonly attribute object algorithm; readonly attribute object usages; }; + +// https://w3c.github.io/webcrypto/#dfn-CryptoKeyPair + +dictionary CryptoKeyPair { + CryptoKey publicKey; + CryptoKey privateKey; +}; diff --git a/tests/wpt/meta/WebCryptoAPI/generateKey/failures_HMAC.https.any.js.ini b/tests/wpt/meta/WebCryptoAPI/generateKey/failures_HMAC.https.any.js.ini deleted file mode 100644 index b479ecbe79b..00000000000 --- a/tests/wpt/meta/WebCryptoAPI/generateKey/failures_HMAC.https.any.js.ini +++ /dev/null @@ -1,98 +0,0 @@ -[failures_HMAC.https.any.worker.html] - [Empty usages: generateKey({hash: SHA-1, length: 160, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-1, length: 160, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-256, length: 256, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-256, length: 256, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-384, length: 384, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-384, length: 384, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-512, length: 512, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-512, length: 512, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-1, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-1, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-256, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-256, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-384, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-384, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-512, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-512, name: HMAC}, true, [\])] - expected: FAIL - - -[failures_HMAC.https.any.html] - [Empty usages: generateKey({hash: SHA-1, length: 160, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-1, length: 160, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-256, length: 256, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-256, length: 256, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-384, length: 384, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-384, length: 384, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-512, length: 512, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-512, length: 512, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-1, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-1, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-256, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-256, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-384, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-384, name: HMAC}, true, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-512, name: HMAC}, false, [\])] - expected: FAIL - - [Empty usages: generateKey({hash: SHA-512, name: HMAC}, true, [\])] - expected: FAIL