script: Unwrap imported key in JWK format after normalizing (#39234)

In our current implementation, the `importKey` method and `unwrapKey`
method of `SubtleCrypto` interface unwrap JsonWebKey before running the
normalized algorithms. Therefore, all cryptography algorithms share the
same unwrapping mechanism. Our current unwrapping mechanism is not
compatible with some cryptography algorithms, which we have not yet
implemented such as Ed25519.

Following the WebCrypto API spec, this patch moves the JsonWebKey
unwrapping mechanism to normalized algorithms so that each cryptography
algorithm can unwrap JsonWebKey in its own way.

This does not introduce behavioral changes, but makes implementing the
unwrap operation for new cryptography algorithms easier in the future.

Remark: Step 8 and 13 of `SubtleCrypto::ImportKey` require the crypto
task source in the script task manager, but we don't have it yet. So,
they're marked as TODO.

Testing: Existing tests should suffice.

---------

Signed-off-by: Kingsley Yung <kingsley@kkoyung.dev>
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Kingsley Yung 2025-09-11 17:38:21 +08:00 committed by GitHub
parent 97690b1cba
commit 5de041e6ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 557 additions and 233 deletions

View file

@ -10,6 +10,7 @@ use js::jsapi::{Heap, JSObject, Value};
use js::rust::HandleObject;
use script_bindings::conversions::SafeToJSValConvertible;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{
CryptoKeyMethods, KeyType, KeyUsage,
};
@ -54,7 +55,7 @@ pub(crate) struct CryptoKey {
algorithm_object: Heap<*mut JSObject>,
/// <https://w3c.github.io/webcrypto/#dom-cryptokey-usages>
usages: Vec<KeyUsage>,
usages: DomRefCell<Vec<KeyUsage>>,
#[no_trace]
handle: Handle,
}
@ -73,7 +74,7 @@ impl CryptoKey {
extractable: Cell::new(extractable),
algorithm,
algorithm_object: Heap::default(),
usages,
usages: DomRefCell::new(usages),
handle,
}
}
@ -110,13 +111,21 @@ impl CryptoKey {
self.algorithm.to_string()
}
pub(crate) fn usages(&self) -> &[KeyUsage] {
&self.usages
pub(crate) fn usages(&self) -> Vec<KeyUsage> {
self.usages.borrow().clone()
}
pub(crate) fn handle(&self) -> &Handle {
&self.handle
}
pub(crate) fn set_extractable(&self, extractable: bool) {
self.extractable.set(extractable);
}
pub(crate) fn set_usages(&self, usages: &[KeyUsage]) {
*self.usages.borrow_mut() = usages.to_owned();
}
}
impl CryptoKeyMethods<crate::DomTypeHolder> for CryptoKey {
@ -138,7 +147,7 @@ impl CryptoKeyMethods<crate::DomTypeHolder> for CryptoKey {
/// <https://w3c.github.io/webcrypto/#dom-cryptokey-usages>
fn Usages(&self, cx: JSContext) -> NonNull<JSObject> {
rooted!(in(*cx) let mut usages: Value);
self.usages.safe_to_jsval(cx, usages.handle_mut());
self.usages.borrow().safe_to_jsval(cx, usages.handle_mut());
NonNull::new(usages.to_object()).unwrap()
}
}