1use std::cell::Cell;
6use std::ptr::NonNull;
7
8use dom_struct::dom_struct;
9use js::jsapi::{Heap, JSObject, Value};
10use js::rust::HandleObject;
11use script_bindings::conversions::SafeToJSValConvertible;
12
13use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{
14 CryptoKeyMethods, KeyType, KeyUsage,
15};
16use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
17use crate::dom::bindings::root::DomRoot;
18use crate::dom::bindings::str::DOMString;
19use crate::dom::globalscope::GlobalScope;
20use crate::script_runtime::{CanGc, JSContext};
21
22#[allow(dead_code)]
24#[derive(MallocSizeOf)]
25pub(crate) enum Handle {
26 Aes128(Vec<u8>),
27 Aes192(Vec<u8>),
28 Aes256(Vec<u8>),
29 Pbkdf2(Vec<u8>),
30 Hkdf(Vec<u8>),
31 Hmac(Vec<u8>),
32}
33
34#[dom_struct]
36pub(crate) struct CryptoKey {
37 reflector_: Reflector,
38
39 key_type: KeyType,
41
42 extractable: Cell<bool>,
44
45 algorithm: DOMString,
51
52 #[ignore_malloc_size_of = "Defined in mozjs"]
54 algorithm_object: Heap<*mut JSObject>,
55
56 usages: Vec<KeyUsage>,
58 #[no_trace]
59 handle: Handle,
60}
61
62impl CryptoKey {
63 fn new_inherited(
64 key_type: KeyType,
65 extractable: bool,
66 usages: Vec<KeyUsage>,
67 algorithm: DOMString,
68 handle: Handle,
69 ) -> CryptoKey {
70 CryptoKey {
71 reflector_: Reflector::new(),
72 key_type,
73 extractable: Cell::new(extractable),
74 algorithm,
75 algorithm_object: Heap::default(),
76 usages,
77 handle,
78 }
79 }
80
81 #[allow(clippy::too_many_arguments)]
82 pub(crate) fn new(
83 global: &GlobalScope,
84 key_type: KeyType,
85 extractable: bool,
86 algorithm: DOMString,
87 algorithm_object: HandleObject,
88 usages: Vec<KeyUsage>,
89 handle: Handle,
90 can_gc: CanGc,
91 ) -> DomRoot<CryptoKey> {
92 let object = reflect_dom_object(
93 Box::new(CryptoKey::new_inherited(
94 key_type,
95 extractable,
96 usages,
97 algorithm,
98 handle,
99 )),
100 global,
101 can_gc,
102 );
103
104 object.algorithm_object.set(algorithm_object.get());
105
106 object
107 }
108
109 pub(crate) fn algorithm(&self) -> String {
110 self.algorithm.to_string()
111 }
112
113 pub(crate) fn usages(&self) -> &[KeyUsage] {
114 &self.usages
115 }
116
117 pub(crate) fn handle(&self) -> &Handle {
118 &self.handle
119 }
120}
121
122impl CryptoKeyMethods<crate::DomTypeHolder> for CryptoKey {
123 fn Type(&self) -> KeyType {
125 self.key_type
126 }
127
128 fn Extractable(&self) -> bool {
130 self.extractable.get()
131 }
132
133 fn Algorithm(&self, _cx: JSContext) -> NonNull<JSObject> {
135 NonNull::new(self.algorithm_object.get()).unwrap()
136 }
137
138 fn Usages(&self, cx: JSContext) -> NonNull<JSObject> {
140 rooted!(in(*cx) let mut usages: Value);
141 self.usages.safe_to_jsval(cx, usages.handle_mut());
142 NonNull::new(usages.to_object()).unwrap()
143 }
144}
145
146impl Handle {
147 pub(crate) fn as_bytes(&self) -> &[u8] {
148 match self {
149 Self::Aes128(bytes) => bytes,
150 Self::Aes192(bytes) => bytes,
151 Self::Aes256(bytes) => bytes,
152 Self::Pbkdf2(bytes) => bytes,
153 Self::Hkdf(bytes) => bytes,
154 Self::Hmac(bytes) => bytes,
155 }
156 }
157}