1/*
2 This file is part of the WebKit open source project.
3 This file has been generated by generate-bindings.pl. DO NOT MODIFY!
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "config.h"
22
23#if ENABLE(WEB_CRYPTO)
24
25#include "JSSubtleCrypto.h"
26
27#include "JSCryptoKey.h"
28#include "JSCryptoKeyUsage.h"
29#include "JSDOMBinding.h"
30#include "JSDOMConstructorNotConstructable.h"
31#include "JSDOMConvertBoolean.h"
32#include "JSDOMConvertBufferSource.h"
33#include "JSDOMConvertDictionary.h"
34#include "JSDOMConvertInterface.h"
35#include "JSDOMConvertNumbers.h"
36#include "JSDOMConvertObject.h"
37#include "JSDOMConvertSequences.h"
38#include "JSDOMConvertStrings.h"
39#include "JSDOMConvertUnion.h"
40#include "JSDOMExceptionHandling.h"
41#include "JSDOMOperation.h"
42#include "JSDOMOperationReturningPromise.h"
43#include "JSDOMWrapperCache.h"
44#include "JSJsonWebKey.h"
45#include "ScriptExecutionContext.h"
46#include <JavaScriptCore/FunctionPrototype.h>
47#include <JavaScriptCore/HeapSnapshotBuilder.h>
48#include <JavaScriptCore/JSArray.h>
49#include <JavaScriptCore/JSCInlines.h>
50#include <JavaScriptCore/JSString.h>
51#include <wtf/GetPtr.h>
52#include <wtf/PointerPreparations.h>
53#include <wtf/URL.h>
54#include <wtf/Variant.h>
55
56
57namespace WebCore {
58using namespace JSC;
59
60String convertEnumerationToString(SubtleCrypto::KeyFormat enumerationValue)
61{
62 static const NeverDestroyed<String> values[] = {
63 MAKE_STATIC_STRING_IMPL("raw"),
64 MAKE_STATIC_STRING_IMPL("spki"),
65 MAKE_STATIC_STRING_IMPL("pkcs8"),
66 MAKE_STATIC_STRING_IMPL("jwk"),
67 };
68 static_assert(static_cast<size_t>(SubtleCrypto::KeyFormat::Raw) == 0, "SubtleCrypto::KeyFormat::Raw is not 0 as expected");
69 static_assert(static_cast<size_t>(SubtleCrypto::KeyFormat::Spki) == 1, "SubtleCrypto::KeyFormat::Spki is not 1 as expected");
70 static_assert(static_cast<size_t>(SubtleCrypto::KeyFormat::Pkcs8) == 2, "SubtleCrypto::KeyFormat::Pkcs8 is not 2 as expected");
71 static_assert(static_cast<size_t>(SubtleCrypto::KeyFormat::Jwk) == 3, "SubtleCrypto::KeyFormat::Jwk is not 3 as expected");
72 ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
73 return values[static_cast<size_t>(enumerationValue)];
74}
75
76template<> JSString* convertEnumerationToJS(ExecState& state, SubtleCrypto::KeyFormat enumerationValue)
77{
78 return jsStringWithCache(&state, convertEnumerationToString(enumerationValue));
79}
80
81template<> Optional<SubtleCrypto::KeyFormat> parseEnumeration<SubtleCrypto::KeyFormat>(ExecState& state, JSValue value)
82{
83 auto stringValue = value.toWTFString(&state);
84 if (stringValue == "raw")
85 return SubtleCrypto::KeyFormat::Raw;
86 if (stringValue == "spki")
87 return SubtleCrypto::KeyFormat::Spki;
88 if (stringValue == "pkcs8")
89 return SubtleCrypto::KeyFormat::Pkcs8;
90 if (stringValue == "jwk")
91 return SubtleCrypto::KeyFormat::Jwk;
92 return WTF::nullopt;
93}
94
95template<> const char* expectedEnumerationValues<SubtleCrypto::KeyFormat>()
96{
97 return "\"raw\", \"spki\", \"pkcs8\", \"jwk\"";
98}
99
100// Functions
101
102JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionEncrypt(JSC::ExecState*);
103JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionDecrypt(JSC::ExecState*);
104JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionSign(JSC::ExecState*);
105JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionVerify(JSC::ExecState*);
106JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionDigest(JSC::ExecState*);
107JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionGenerateKey(JSC::ExecState*);
108JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionDeriveKey(JSC::ExecState*);
109JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionDeriveBits(JSC::ExecState*);
110JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionImportKey(JSC::ExecState*);
111JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionExportKey(JSC::ExecState*);
112JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionWrapKey(JSC::ExecState*);
113JSC::EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionUnwrapKey(JSC::ExecState*);
114
115// Attributes
116
117JSC::EncodedJSValue jsSubtleCryptoConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
118bool setJSSubtleCryptoConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
119
120class JSSubtleCryptoPrototype : public JSC::JSNonFinalObject {
121public:
122 using Base = JSC::JSNonFinalObject;
123 static JSSubtleCryptoPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
124 {
125 JSSubtleCryptoPrototype* ptr = new (NotNull, JSC::allocateCell<JSSubtleCryptoPrototype>(vm.heap)) JSSubtleCryptoPrototype(vm, globalObject, structure);
126 ptr->finishCreation(vm);
127 return ptr;
128 }
129
130 DECLARE_INFO;
131 static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
132 {
133 return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
134 }
135
136private:
137 JSSubtleCryptoPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
138 : JSC::JSNonFinalObject(vm, structure)
139 {
140 }
141
142 void finishCreation(JSC::VM&);
143};
144
145using JSSubtleCryptoConstructor = JSDOMConstructorNotConstructable<JSSubtleCrypto>;
146
147template<> JSValue JSSubtleCryptoConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
148{
149 UNUSED_PARAM(vm);
150 return globalObject.functionPrototype();
151}
152
153template<> void JSSubtleCryptoConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
154{
155 putDirect(vm, vm.propertyNames->prototype, JSSubtleCrypto::prototype(vm, globalObject), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
156 putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String("SubtleCrypto"_s)), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
157 putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
158}
159
160template<> const ClassInfo JSSubtleCryptoConstructor::s_info = { "SubtleCrypto", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSubtleCryptoConstructor) };
161
162/* Hash table for prototype */
163
164static const HashTableValue JSSubtleCryptoPrototypeTableValues[] =
165{
166 { "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSubtleCryptoConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSSubtleCryptoConstructor) } },
167 { "encrypt", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionEncrypt), (intptr_t) (3) } },
168 { "decrypt", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionDecrypt), (intptr_t) (3) } },
169 { "sign", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionSign), (intptr_t) (3) } },
170 { "verify", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionVerify), (intptr_t) (4) } },
171 { "digest", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionDigest), (intptr_t) (2) } },
172 { "generateKey", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionGenerateKey), (intptr_t) (3) } },
173 { "deriveKey", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionDeriveKey), (intptr_t) (5) } },
174 { "deriveBits", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionDeriveBits), (intptr_t) (3) } },
175 { "importKey", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionImportKey), (intptr_t) (5) } },
176 { "exportKey", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionExportKey), (intptr_t) (2) } },
177 { "wrapKey", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionWrapKey), (intptr_t) (4) } },
178 { "unwrapKey", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSubtleCryptoPrototypeFunctionUnwrapKey), (intptr_t) (7) } },
179};
180
181const ClassInfo JSSubtleCryptoPrototype::s_info = { "SubtleCryptoPrototype", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSubtleCryptoPrototype) };
182
183void JSSubtleCryptoPrototype::finishCreation(VM& vm)
184{
185 Base::finishCreation(vm);
186 reifyStaticProperties(vm, JSSubtleCrypto::info(), JSSubtleCryptoPrototypeTableValues, *this);
187}
188
189const ClassInfo JSSubtleCrypto::s_info = { "SubtleCrypto", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSubtleCrypto) };
190
191JSSubtleCrypto::JSSubtleCrypto(Structure* structure, JSDOMGlobalObject& globalObject, Ref<SubtleCrypto>&& impl)
192 : JSDOMWrapper<SubtleCrypto>(structure, globalObject, WTFMove(impl))
193{
194}
195
196void JSSubtleCrypto::finishCreation(VM& vm)
197{
198 Base::finishCreation(vm);
199 ASSERT(inherits(vm, info()));
200
201}
202
203JSObject* JSSubtleCrypto::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
204{
205 return JSSubtleCryptoPrototype::create(vm, &globalObject, JSSubtleCryptoPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
206}
207
208JSObject* JSSubtleCrypto::prototype(VM& vm, JSDOMGlobalObject& globalObject)
209{
210 return getDOMPrototype<JSSubtleCrypto>(vm, globalObject);
211}
212
213JSValue JSSubtleCrypto::getConstructor(VM& vm, const JSGlobalObject* globalObject)
214{
215 return getDOMConstructor<JSSubtleCryptoConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
216}
217
218void JSSubtleCrypto::destroy(JSC::JSCell* cell)
219{
220 JSSubtleCrypto* thisObject = static_cast<JSSubtleCrypto*>(cell);
221 thisObject->JSSubtleCrypto::~JSSubtleCrypto();
222}
223
224template<> inline JSSubtleCrypto* IDLOperation<JSSubtleCrypto>::cast(ExecState& state)
225{
226 return jsDynamicCast<JSSubtleCrypto*>(state.vm(), state.thisValue());
227}
228
229EncodedJSValue jsSubtleCryptoConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
230{
231 VM& vm = state->vm();
232 auto throwScope = DECLARE_THROW_SCOPE(vm);
233 auto* prototype = jsDynamicCast<JSSubtleCryptoPrototype*>(vm, JSValue::decode(thisValue));
234 if (UNLIKELY(!prototype))
235 return throwVMTypeError(state, throwScope);
236 return JSValue::encode(JSSubtleCrypto::getConstructor(state->vm(), prototype->globalObject()));
237}
238
239bool setJSSubtleCryptoConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
240{
241 VM& vm = state->vm();
242 auto throwScope = DECLARE_THROW_SCOPE(vm);
243 auto* prototype = jsDynamicCast<JSSubtleCryptoPrototype*>(vm, JSValue::decode(thisValue));
244 if (UNLIKELY(!prototype)) {
245 throwVMTypeError(state, throwScope);
246 return false;
247 }
248 // Shadowing a built-in constructor
249 return prototype->putDirect(vm, vm.propertyNames->constructor, JSValue::decode(encodedValue));
250}
251
252static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionEncryptBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
253{
254 UNUSED_PARAM(state);
255 UNUSED_PARAM(throwScope);
256 auto& impl = castedThis->wrapped();
257 if (UNLIKELY(state->argumentCount() < 3))
258 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
259 auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(0));
260 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
261 auto key = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(1), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 1, "key", "SubtleCrypto", "encrypt", "CryptoKey"); });
262 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
263 auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*state, state->uncheckedArgument(2));
264 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
265 impl.encrypt(*state, WTFMove(algorithm), *key, WTFMove(data), WTFMove(promise));
266 return JSValue::encode(jsUndefined());
267}
268
269EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionEncrypt(ExecState* state)
270{
271 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionEncryptBody, PromiseExecutionScope::WindowOrWorker>(*state, "encrypt");
272}
273
274static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionDecryptBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
275{
276 UNUSED_PARAM(state);
277 UNUSED_PARAM(throwScope);
278 auto& impl = castedThis->wrapped();
279 if (UNLIKELY(state->argumentCount() < 3))
280 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
281 auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(0));
282 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
283 auto key = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(1), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 1, "key", "SubtleCrypto", "decrypt", "CryptoKey"); });
284 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
285 auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*state, state->uncheckedArgument(2));
286 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
287 impl.decrypt(*state, WTFMove(algorithm), *key, WTFMove(data), WTFMove(promise));
288 return JSValue::encode(jsUndefined());
289}
290
291EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionDecrypt(ExecState* state)
292{
293 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionDecryptBody, PromiseExecutionScope::WindowOrWorker>(*state, "decrypt");
294}
295
296static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionSignBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
297{
298 UNUSED_PARAM(state);
299 UNUSED_PARAM(throwScope);
300 auto& impl = castedThis->wrapped();
301 if (UNLIKELY(state->argumentCount() < 3))
302 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
303 auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(0));
304 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
305 auto key = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(1), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 1, "key", "SubtleCrypto", "sign", "CryptoKey"); });
306 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
307 auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*state, state->uncheckedArgument(2));
308 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
309 impl.sign(*state, WTFMove(algorithm), *key, WTFMove(data), WTFMove(promise));
310 return JSValue::encode(jsUndefined());
311}
312
313EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionSign(ExecState* state)
314{
315 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionSignBody, PromiseExecutionScope::WindowOrWorker>(*state, "sign");
316}
317
318static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionVerifyBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
319{
320 UNUSED_PARAM(state);
321 UNUSED_PARAM(throwScope);
322 auto& impl = castedThis->wrapped();
323 if (UNLIKELY(state->argumentCount() < 4))
324 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
325 auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(0));
326 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
327 auto key = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(1), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 1, "key", "SubtleCrypto", "verify", "CryptoKey"); });
328 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
329 auto signature = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*state, state->uncheckedArgument(2));
330 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
331 auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*state, state->uncheckedArgument(3));
332 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
333 impl.verify(*state, WTFMove(algorithm), *key, WTFMove(signature), WTFMove(data), WTFMove(promise));
334 return JSValue::encode(jsUndefined());
335}
336
337EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionVerify(ExecState* state)
338{
339 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionVerifyBody, PromiseExecutionScope::WindowOrWorker>(*state, "verify");
340}
341
342static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionDigestBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
343{
344 UNUSED_PARAM(state);
345 UNUSED_PARAM(throwScope);
346 auto& impl = castedThis->wrapped();
347 if (UNLIKELY(state->argumentCount() < 2))
348 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
349 auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(0));
350 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
351 auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*state, state->uncheckedArgument(1));
352 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
353 impl.digest(*state, WTFMove(algorithm), WTFMove(data), WTFMove(promise));
354 return JSValue::encode(jsUndefined());
355}
356
357EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionDigest(ExecState* state)
358{
359 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionDigestBody, PromiseExecutionScope::WindowOrWorker>(*state, "digest");
360}
361
362static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionGenerateKeyBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
363{
364 UNUSED_PARAM(state);
365 UNUSED_PARAM(throwScope);
366 auto& impl = castedThis->wrapped();
367 if (UNLIKELY(state->argumentCount() < 3))
368 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
369 auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(0));
370 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
371 auto extractable = convert<IDLBoolean>(*state, state->uncheckedArgument(1));
372 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
373 auto keyUsages = convert<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(*state, state->uncheckedArgument(2));
374 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
375 impl.generateKey(*state, WTFMove(algorithm), WTFMove(extractable), WTFMove(keyUsages), WTFMove(promise));
376 return JSValue::encode(jsUndefined());
377}
378
379EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionGenerateKey(ExecState* state)
380{
381 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionGenerateKeyBody, PromiseExecutionScope::WindowOrWorker>(*state, "generateKey");
382}
383
384static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionDeriveKeyBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
385{
386 UNUSED_PARAM(state);
387 UNUSED_PARAM(throwScope);
388 auto& impl = castedThis->wrapped();
389 if (UNLIKELY(state->argumentCount() < 5))
390 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
391 auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(0));
392 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
393 auto baseKey = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(1), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 1, "baseKey", "SubtleCrypto", "deriveKey", "CryptoKey"); });
394 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
395 auto derivedKeyType = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(2));
396 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
397 auto extractable = convert<IDLBoolean>(*state, state->uncheckedArgument(3));
398 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
399 auto keyUsages = convert<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(*state, state->uncheckedArgument(4));
400 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
401 impl.deriveKey(*state, WTFMove(algorithm), *baseKey, WTFMove(derivedKeyType), WTFMove(extractable), WTFMove(keyUsages), WTFMove(promise));
402 return JSValue::encode(jsUndefined());
403}
404
405EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionDeriveKey(ExecState* state)
406{
407 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionDeriveKeyBody, PromiseExecutionScope::WindowOrWorker>(*state, "deriveKey");
408}
409
410static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionDeriveBitsBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
411{
412 UNUSED_PARAM(state);
413 UNUSED_PARAM(throwScope);
414 auto& impl = castedThis->wrapped();
415 if (UNLIKELY(state->argumentCount() < 3))
416 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
417 auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(0));
418 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
419 auto baseKey = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(1), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 1, "baseKey", "SubtleCrypto", "deriveBits", "CryptoKey"); });
420 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
421 auto length = convert<IDLUnsignedLong>(*state, state->uncheckedArgument(2));
422 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
423 impl.deriveBits(*state, WTFMove(algorithm), *baseKey, WTFMove(length), WTFMove(promise));
424 return JSValue::encode(jsUndefined());
425}
426
427EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionDeriveBits(ExecState* state)
428{
429 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionDeriveBitsBody, PromiseExecutionScope::WindowOrWorker>(*state, "deriveBits");
430}
431
432static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionImportKeyBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
433{
434 UNUSED_PARAM(state);
435 UNUSED_PARAM(throwScope);
436 auto& impl = castedThis->wrapped();
437 if (UNLIKELY(state->argumentCount() < 5))
438 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
439 auto format = convert<IDLEnumeration<SubtleCrypto::KeyFormat>>(*state, state->uncheckedArgument(0), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentMustBeEnumError(state, scope, 0, "format", "SubtleCrypto", "importKey", expectedEnumerationValues<SubtleCrypto::KeyFormat>()); });
440 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
441 auto keyData = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer, IDLDictionary<JsonWebKey>>>(*state, state->uncheckedArgument(1));
442 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
443 auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(2));
444 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
445 auto extractable = convert<IDLBoolean>(*state, state->uncheckedArgument(3));
446 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
447 auto keyUsages = convert<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(*state, state->uncheckedArgument(4));
448 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
449 impl.importKey(*state, WTFMove(format), WTFMove(keyData), WTFMove(algorithm), WTFMove(extractable), WTFMove(keyUsages), WTFMove(promise));
450 return JSValue::encode(jsUndefined());
451}
452
453EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionImportKey(ExecState* state)
454{
455 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionImportKeyBody, PromiseExecutionScope::WindowOrWorker>(*state, "importKey");
456}
457
458static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionExportKeyBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
459{
460 UNUSED_PARAM(state);
461 UNUSED_PARAM(throwScope);
462 auto& impl = castedThis->wrapped();
463 if (UNLIKELY(state->argumentCount() < 2))
464 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
465 auto format = convert<IDLEnumeration<SubtleCrypto::KeyFormat>>(*state, state->uncheckedArgument(0), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentMustBeEnumError(state, scope, 0, "format", "SubtleCrypto", "exportKey", expectedEnumerationValues<SubtleCrypto::KeyFormat>()); });
466 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
467 auto key = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(1), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 1, "key", "SubtleCrypto", "exportKey", "CryptoKey"); });
468 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
469 impl.exportKey(WTFMove(format), *key, WTFMove(promise));
470 return JSValue::encode(jsUndefined());
471}
472
473EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionExportKey(ExecState* state)
474{
475 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionExportKeyBody, PromiseExecutionScope::WindowOrWorker>(*state, "exportKey");
476}
477
478static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionWrapKeyBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
479{
480 UNUSED_PARAM(state);
481 UNUSED_PARAM(throwScope);
482 auto& impl = castedThis->wrapped();
483 if (UNLIKELY(state->argumentCount() < 4))
484 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
485 auto format = convert<IDLEnumeration<SubtleCrypto::KeyFormat>>(*state, state->uncheckedArgument(0), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentMustBeEnumError(state, scope, 0, "format", "SubtleCrypto", "wrapKey", expectedEnumerationValues<SubtleCrypto::KeyFormat>()); });
486 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
487 auto key = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(1), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 1, "key", "SubtleCrypto", "wrapKey", "CryptoKey"); });
488 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
489 auto wrappingKey = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(2), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 2, "wrappingKey", "SubtleCrypto", "wrapKey", "CryptoKey"); });
490 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
491 auto wrapAlgorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(3));
492 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
493 impl.wrapKey(*state, WTFMove(format), *key, *wrappingKey, WTFMove(wrapAlgorithm), WTFMove(promise));
494 return JSValue::encode(jsUndefined());
495}
496
497EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionWrapKey(ExecState* state)
498{
499 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionWrapKeyBody, PromiseExecutionScope::WindowOrWorker>(*state, "wrapKey");
500}
501
502static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunctionUnwrapKeyBody(JSC::ExecState* state, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise, JSC::ThrowScope& throwScope)
503{
504 UNUSED_PARAM(state);
505 UNUSED_PARAM(throwScope);
506 auto& impl = castedThis->wrapped();
507 if (UNLIKELY(state->argumentCount() < 7))
508 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
509 auto format = convert<IDLEnumeration<SubtleCrypto::KeyFormat>>(*state, state->uncheckedArgument(0), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentMustBeEnumError(state, scope, 0, "format", "SubtleCrypto", "unwrapKey", expectedEnumerationValues<SubtleCrypto::KeyFormat>()); });
510 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
511 auto wrappedKey = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*state, state->uncheckedArgument(1));
512 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
513 auto unwrappingKey = convert<IDLInterface<CryptoKey>>(*state, state->uncheckedArgument(2), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 2, "unwrappingKey", "SubtleCrypto", "unwrapKey", "CryptoKey"); });
514 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
515 auto unwrapAlgorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(3));
516 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
517 auto unwrappedKeyAlgorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*state, state->uncheckedArgument(4));
518 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
519 auto extractable = convert<IDLBoolean>(*state, state->uncheckedArgument(5));
520 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
521 auto keyUsages = convert<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(*state, state->uncheckedArgument(6));
522 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
523 impl.unwrapKey(*state, WTFMove(format), WTFMove(wrappedKey), *unwrappingKey, WTFMove(unwrapAlgorithm), WTFMove(unwrappedKeyAlgorithm), WTFMove(extractable), WTFMove(keyUsages), WTFMove(promise));
524 return JSValue::encode(jsUndefined());
525}
526
527EncodedJSValue JSC_HOST_CALL jsSubtleCryptoPrototypeFunctionUnwrapKey(ExecState* state)
528{
529 return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunctionUnwrapKeyBody, PromiseExecutionScope::WindowOrWorker>(*state, "unwrapKey");
530}
531
532void JSSubtleCrypto::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
533{
534 auto* thisObject = jsCast<JSSubtleCrypto*>(cell);
535 builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
536 if (thisObject->scriptExecutionContext())
537 builder.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
538 Base::heapSnapshot(cell, builder);
539}
540
541bool JSSubtleCryptoOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
542{
543 auto* jsSubtleCrypto = jsCast<JSSubtleCrypto*>(handle.slot()->asCell());
544 ScriptExecutionContext* root = WTF::getPtr(jsSubtleCrypto->wrapped().scriptExecutionContext());
545 if (!root)
546 return false;
547 if (UNLIKELY(reason))
548 *reason = "Reachable from ScriptExecutionContext";
549 return visitor.containsOpaqueRoot(root);
550}
551
552void JSSubtleCryptoOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
553{
554 auto* jsSubtleCrypto = static_cast<JSSubtleCrypto*>(handle.slot()->asCell());
555 auto& world = *static_cast<DOMWrapperWorld*>(context);
556 uncacheWrapper(world, &jsSubtleCrypto->wrapped(), jsSubtleCrypto);
557}
558
559#if ENABLE(BINDING_INTEGRITY)
560#if PLATFORM(WIN)
561#pragma warning(disable: 4483)
562extern "C" { extern void (*const __identifier("??_7SubtleCrypto@WebCore@@6B@")[])(); }
563#else
564extern "C" { extern void* _ZTVN7WebCore12SubtleCryptoE[]; }
565#endif
566#endif
567
568JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<SubtleCrypto>&& impl)
569{
570
571#if ENABLE(BINDING_INTEGRITY)
572 void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
573#if PLATFORM(WIN)
574 void* expectedVTablePointer = WTF_PREPARE_VTBL_POINTER_FOR_INSPECTION(__identifier("??_7SubtleCrypto@WebCore@@6B@"));
575#else
576 void* expectedVTablePointer = WTF_PREPARE_VTBL_POINTER_FOR_INSPECTION(&_ZTVN7WebCore12SubtleCryptoE[2]);
577#endif
578
579 // If this fails SubtleCrypto does not have a vtable, so you need to add the
580 // ImplementationLacksVTable attribute to the interface definition
581 static_assert(std::is_polymorphic<SubtleCrypto>::value, "SubtleCrypto is not polymorphic");
582
583 // If you hit this assertion you either have a use after free bug, or
584 // SubtleCrypto has subclasses. If SubtleCrypto has subclasses that get passed
585 // to toJS() we currently require SubtleCrypto you to opt out of binding hardening
586 // by adding the SkipVTableValidation attribute to the interface IDL definition
587 RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
588#endif
589 return createWrapper<SubtleCrypto>(globalObject, WTFMove(impl));
590}
591
592JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, SubtleCrypto& impl)
593{
594 return wrap(state, globalObject, impl);
595}
596
597SubtleCrypto* JSSubtleCrypto::toWrapped(JSC::VM& vm, JSC::JSValue value)
598{
599 if (auto* wrapper = jsDynamicCast<JSSubtleCrypto*>(vm, value))
600 return &wrapper->wrapped();
601 return nullptr;
602}
603
604}
605
606#endif // ENABLE(WEB_CRYPTO)
607