summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2021-09-30 20:02:55 +0300
committerAndreas Kling <kling@serenityos.org>2021-09-30 20:02:09 +0200
commit2c6c9b73c88bd2feea66df8766212c2e586ea9aa (patch)
treeb1e0712844874577ac463a506e9164e93b93493f /Userland
parentbecbb0ea97bf2da194246f1dde1d2b8fba16946d (diff)
downloadserenity-2c6c9b73c88bd2feea66df8766212c2e586ea9aa.zip
LibWeb: Add the Web::Crypto namespace, built-in, and getRandomValues
Since we don't support IDL typedefs or unions yet, the responsibility of verifying the type of the argument is temporarily moved from the generated Wrapper to the implementation.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/Bindings/WindowObject.cpp14
-rw-r--r--Userland/Libraries/LibWeb/Bindings/WindowObject.h2
-rw-r--r--Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h3
-rw-r--r--Userland/Libraries/LibWeb/CMakeLists.txt2
-rw-r--r--Userland/Libraries/LibWeb/Crypto/Crypto.cpp37
-rw-r--r--Userland/Libraries/LibWeb/Crypto/Crypto.h38
-rw-r--r--Userland/Libraries/LibWeb/Crypto/Crypto.idl7
-rw-r--r--Userland/Libraries/LibWeb/DOM/Window.cpp2
-rw-r--r--Userland/Libraries/LibWeb/DOM/Window.h3
-rw-r--r--Userland/Libraries/LibWeb/Forward.h5
-rw-r--r--Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp4
11 files changed, 113 insertions, 4 deletions
diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp
index 612a2db08d..4492a47c41 100644
--- a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp
+++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp
@@ -14,6 +14,7 @@
#include <LibJS/Runtime/Shape.h>
#include <LibTextCodec/Decoder.h>
#include <LibWeb/Bindings/CSSStyleDeclarationWrapper.h>
+#include <LibWeb/Bindings/CryptoWrapper.h>
#include <LibWeb/Bindings/DocumentWrapper.h>
#include <LibWeb/Bindings/ElementWrapper.h>
#include <LibWeb/Bindings/EventTargetConstructor.h>
@@ -30,6 +31,8 @@
#include <LibWeb/Bindings/Replaceable.h>
#include <LibWeb/Bindings/ScreenWrapper.h>
#include <LibWeb/Bindings/WindowObject.h>
+#include <LibWeb/Bindings/WindowObjectHelper.h>
+#include <LibWeb/Crypto/Crypto.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Event.h>
#include <LibWeb/DOM/Window.h>
@@ -39,8 +42,6 @@
#include <LibWeb/Page/Page.h>
#include <LibWeb/WebAssembly/WebAssemblyObject.h>
-#include <LibWeb/Bindings/WindowObjectHelper.h>
-
namespace Web::Bindings {
WindowObject::WindowObject(DOM::Window& impl)
@@ -65,6 +66,7 @@ void WindowObject::initialize_global_object()
define_native_accessor("document", document_getter, {}, JS::Attribute::Enumerable);
define_native_accessor("history", history_getter, {}, JS::Attribute::Enumerable);
define_native_accessor("performance", performance_getter, {}, JS::Attribute::Enumerable);
+ define_native_accessor("crypto", crypto_getter, {}, JS::Attribute::Enumerable);
define_native_accessor("screen", screen_getter, {}, JS::Attribute::Enumerable);
define_native_accessor("innerWidth", inner_width_getter, {}, JS::Attribute::Enumerable);
define_native_accessor("innerHeight", inner_height_getter, {}, JS::Attribute::Enumerable);
@@ -497,6 +499,14 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::event_setter)
REPLACEABLE_PROPERTY_SETTER(WindowObject, event);
}
+JS_DEFINE_NATIVE_FUNCTION(WindowObject::crypto_getter)
+{
+ auto* impl = impl_from(vm, global_object);
+ if (!impl)
+ return {};
+ return wrap(global_object, impl->crypto());
+}
+
JS_DEFINE_NATIVE_FUNCTION(WindowObject::inner_width_getter)
{
auto* impl = impl_from(vm, global_object);
diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.h b/Userland/Libraries/LibWeb/Bindings/WindowObject.h
index 911a93bee7..2fb2609c53 100644
--- a/Userland/Libraries/LibWeb/Bindings/WindowObject.h
+++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.h
@@ -111,6 +111,8 @@ private:
JS_DECLARE_NATIVE_FUNCTION(queue_microtask);
+ JS_DECLARE_NATIVE_FUNCTION(crypto_getter);
+
#define __ENUMERATE(attribute, event_name) \
JS_DECLARE_NATIVE_FUNCTION(attribute##_getter); \
JS_DECLARE_NATIVE_FUNCTION(attribute##_setter);
diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h
index b18f0d2346..742db85dba 100644
--- a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h
+++ b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h
@@ -30,6 +30,8 @@
#include <LibWeb/Bindings/CloseEventPrototype.h>
#include <LibWeb/Bindings/CommentConstructor.h>
#include <LibWeb/Bindings/CommentPrototype.h>
+#include <LibWeb/Bindings/CryptoConstructor.h>
+#include <LibWeb/Bindings/CryptoPrototype.h>
#include <LibWeb/Bindings/CustomEventConstructor.h>
#include <LibWeb/Bindings/CustomEventPrototype.h>
#include <LibWeb/Bindings/DOMExceptionConstructor.h>
@@ -271,6 +273,7 @@
auto& vm = this->vm(); \
ADD_WINDOW_OBJECT_INTERFACE(AbortController) \
ADD_WINDOW_OBJECT_INTERFACE(AbortSignal) \
+ ADD_WINDOW_OBJECT_INTERFACE(Crypto) \
ADD_WINDOW_OBJECT_INTERFACE(CSSRule) \
ADD_WINDOW_OBJECT_INTERFACE(CSSRuleList) \
ADD_WINDOW_OBJECT_INTERFACE(CSSStyleDeclaration) \
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt
index d530f17050..a2f0517ea0 100644
--- a/Userland/Libraries/LibWeb/CMakeLists.txt
+++ b/Userland/Libraries/LibWeb/CMakeLists.txt
@@ -13,6 +13,7 @@ set(SOURCES
Bindings/ScriptExecutionContext.cpp
Bindings/WindowObject.cpp
Bindings/Wrappable.cpp
+ Crypto/Crypto.cpp
CSS/CSSConditionRule.cpp
CSS/CSSGroupingRule.cpp
CSS/CSSImportRule.cpp
@@ -341,6 +342,7 @@ function(libweb_js_wrapper class)
add_dependencies(all_generated generate_${basename}Prototype.cpp)
endfunction()
+libweb_js_wrapper(Crypto/Crypto)
libweb_js_wrapper(CSS/CSSRule)
libweb_js_wrapper(CSS/CSSRuleList)
libweb_js_wrapper(CSS/CSSStyleDeclaration)
diff --git a/Userland/Libraries/LibWeb/Crypto/Crypto.cpp b/Userland/Libraries/LibWeb/Crypto/Crypto.cpp
new file mode 100644
index 0000000000..64ba54f6ed
--- /dev/null
+++ b/Userland/Libraries/LibWeb/Crypto/Crypto.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/Random.h>
+#include <LibJS/Runtime/TypedArray.h>
+#include <LibWeb/Bindings/Wrapper.h>
+#include <LibWeb/Crypto/Crypto.h>
+
+namespace Web::Crypto {
+
+DOM::ExceptionOr<JS::Value> Crypto::get_random_values(JS::Value array) const
+{
+ // 1. If array is not an Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array, then throw a TypeMismatchError and terminate the algorithm.
+ if (!array.is_object() || !(is<JS::Int8Array>(array.as_object()) || is<JS::Uint8Array>(array.as_object()) || is<JS::Uint8ClampedArray>(array.as_object()) || is<JS::Int16Array>(array.as_object()) || is<JS::Uint16Array>(array.as_object()) || is<JS::Int32Array>(array.as_object()) || is<JS::Uint32Array>(array.as_object()) || is<JS::BigInt64Array>(array.as_object()) || is<JS::BigUint64Array>(array.as_object())))
+ return DOM::TypeMismatchError::create("array must be one of Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array");
+ auto& typed_array = static_cast<JS::TypedArrayBase&>(array.as_object());
+
+ // 2. If the byteLength of array is greater than 65536, throw a QuotaExceededError and terminate the algorithm.
+ if (typed_array.byte_length() > 65536)
+ return DOM::QuotaExceededError::create("array's byteLength may not be greater than 65536");
+
+ // IMPLEMENTATION DEFINED: If the viewed array buffer is detached, throw a InvalidStateError and terminate the algorithm.
+ if (typed_array.viewed_array_buffer()->is_detached())
+ return DOM::InvalidStateError::create("array is detached");
+ // FIXME: Handle SharedArrayBuffers
+
+ // 3. Overwrite all elements of array with cryptographically strong random values of the appropriate type.
+ fill_with_random(typed_array.viewed_array_buffer()->buffer().data(), typed_array.viewed_array_buffer()->buffer().size());
+
+ // 4. Return array.
+ return array;
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/Crypto/Crypto.h b/Userland/Libraries/LibWeb/Crypto/Crypto.h
new file mode 100644
index 0000000000..d469b7a48f
--- /dev/null
+++ b/Userland/Libraries/LibWeb/Crypto/Crypto.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibJS/Runtime/Value.h>
+#include <LibWeb/Bindings/Wrappable.h>
+#include <LibWeb/DOM/ExceptionOr.h>
+
+namespace Web::Crypto {
+
+class Crypto : public Bindings::Wrappable
+ , public RefCounted<Crypto>
+ , public Weakable<Crypto> {
+public:
+ using WrapperType = Bindings::CryptoWrapper;
+
+ static NonnullRefPtr<Crypto> create()
+ {
+ return adopt_ref(*new Crypto());
+ }
+
+ DOM::ExceptionOr<JS::Value> get_random_values(JS::Value array) const;
+
+private:
+ Crypto() = default;
+};
+
+}
+
+namespace Web::Bindings {
+
+CryptoWrapper* wrap(JS::GlobalObject&, Crypto::Crypto&);
+
+}
diff --git a/Userland/Libraries/LibWeb/Crypto/Crypto.idl b/Userland/Libraries/LibWeb/Crypto/Crypto.idl
new file mode 100644
index 0000000000..64941a4980
--- /dev/null
+++ b/Userland/Libraries/LibWeb/Crypto/Crypto.idl
@@ -0,0 +1,7 @@
+[Exposed=(Window,Worker)]
+interface Crypto {
+ // TODO: [SecureContext] readonly attribute SubtleCrypto subtle;
+
+ // FIXME: the argument and the return value should be of type ArrayBufferView
+ any getRandomValues(any array);
+};
diff --git a/Userland/Libraries/LibWeb/DOM/Window.cpp b/Userland/Libraries/LibWeb/DOM/Window.cpp
index 7ca96a76c9..c476b0c38f 100644
--- a/Userland/Libraries/LibWeb/DOM/Window.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Window.cpp
@@ -7,6 +7,7 @@
#include <LibGUI/DisplayLink.h>
#include <LibJS/Runtime/FunctionObject.h>
#include <LibWeb/CSS/ResolvedCSSStyleDeclaration.h>
+#include <LibWeb/Crypto/Crypto.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Event.h>
#include <LibWeb/DOM/EventDispatcher.h>
@@ -94,6 +95,7 @@ Window::Window(Document& document)
: EventTarget(static_cast<Bindings::ScriptExecutionContext&>(document))
, m_associated_document(document)
, m_performance(make<HighResolutionTime::Performance>(*this))
+ , m_crypto(Crypto::Crypto::create())
, m_screen(CSS::Screen::create(*this))
{
}
diff --git a/Userland/Libraries/LibWeb/DOM/Window.h b/Userland/Libraries/LibWeb/DOM/Window.h
index 5199fa3bf6..871da29dec 100644
--- a/Userland/Libraries/LibWeb/DOM/Window.h
+++ b/Userland/Libraries/LibWeb/DOM/Window.h
@@ -74,6 +74,8 @@ public:
HighResolutionTime::Performance& performance() { return *m_performance; }
+ Crypto::Crypto& crypto() { return *m_crypto; }
+
CSS::Screen& screen() { return *m_screen; }
Event const* current_event() const { return m_current_event; }
@@ -107,6 +109,7 @@ private:
HashMap<int, NonnullRefPtr<Timer>> m_timers;
NonnullOwnPtr<HighResolutionTime::Performance> m_performance;
+ NonnullRefPtr<Crypto::Crypto> m_crypto;
NonnullRefPtr<CSS::Screen> m_screen;
RefPtr<Event> m_current_event;
diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h
index 6ef1f9c6c7..66f27a3e00 100644
--- a/Userland/Libraries/LibWeb/Forward.h
+++ b/Userland/Libraries/LibWeb/Forward.h
@@ -13,6 +13,10 @@ struct ParsedCookie;
enum class Source;
}
+namespace Web::Crypto {
+class Crypto;
+}
+
namespace Web::CSS {
class CalculatedStyleValue;
class CSSRule;
@@ -262,6 +266,7 @@ class URLSearchParamsIterator;
namespace Web::Bindings {
class AbortControllerWrapper;
class AbortSignalWrapper;
+class CryptoWrapper;
class CSSRuleListWrapper;
class CSSRuleWrapper;
class CSSStyleDeclarationWrapper;
diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp
index 8511d69aaa..e95333b82c 100644
--- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp
+++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp
@@ -361,7 +361,7 @@ JS::Value to_js_value(Wasm::Value& wasm_value, JS::GlobalObject& global_object)
{
switch (wasm_value.type().kind()) {
case Wasm::ValueType::I64:
- return global_object.heap().allocate<JS::BigInt>(global_object, Crypto::SignedBigInteger::create_from(wasm_value.to<i64>().value()));
+ return global_object.heap().allocate<JS::BigInt>(global_object, ::Crypto::SignedBigInteger::create_from(wasm_value.to<i64>().value()));
case Wasm::ValueType::I32:
return JS::Value(wasm_value.to<i32>().value());
case Wasm::ValueType::F64:
@@ -382,7 +382,7 @@ JS::Value to_js_value(Wasm::Value& wasm_value, JS::GlobalObject& global_object)
Optional<Wasm::Value> to_webassembly_value(JS::Value value, const Wasm::ValueType& type, JS::GlobalObject& global_object)
{
- static Crypto::SignedBigInteger two_64 = "1"_sbigint.shift_left(64);
+ static ::Crypto::SignedBigInteger two_64 = "1"_sbigint.shift_left(64);
auto& vm = global_object.vm();
switch (type.kind()) {