summaryrefslogtreecommitdiff
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
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.
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp22
-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
12 files changed, 129 insertions, 10 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp
index 1e86f07c1c..ce258404eb 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp
@@ -726,7 +726,7 @@ int main(int argc, char** argv)
auto data = file_or_error.value()->read_all();
auto interface = IDL::parse_interface(path, data);
- if (namespace_.is_one_of("CSS", "DOM", "HTML", "UIEvents", "Geometry", "HighResolutionTime", "NavigationTiming", "RequestIdleCallback", "SVG", "XHR", "URL")) {
+ if (namespace_.is_one_of("Crypto", "CSS", "DOM", "HTML", "UIEvents", "Geometry", "HighResolutionTime", "NavigationTiming", "RequestIdleCallback", "SVG", "XHR", "URL")) {
StringBuilder builder;
builder.append(namespace_);
builder.append("::");
@@ -1346,7 +1346,9 @@ static void generate_header(IDL::Interface const& interface)
#include <LibWeb/Bindings/Wrapper.h>
// FIXME: This is very strange.
-#if __has_include(<LibWeb/CSS/@name@.h>)
+#if __has_include(<LibWeb/Crypto/@name@.h>)
+# include <LibWeb/Crypto/@name@.h>
+#elif __has_include(<LibWeb/CSS/@name@.h>)
# include <LibWeb/CSS/@name@.h>
#elif __has_include(<LibWeb/DOM/@name@.h>)
# include <LibWeb/DOM/@name@.h>
@@ -2428,7 +2430,9 @@ void generate_constructor_implementation(IDL::Interface const& interface)
#include <LibWeb/Bindings/@wrapper_class@.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/WindowObject.h>
-#if __has_include(<LibWeb/CSS/@name@.h>)
+#if __has_include(<LibWeb/Crypto/@name@.h>)
+# include <LibWeb/Crypto/@name@.h>
+#elif __has_include(<LibWeb/CSS/@name@.h>)
# include <LibWeb/CSS/@name@.h>
#elif __has_include(<LibWeb/DOM/@name@.h>)
# include <LibWeb/DOM/@name@.h>
@@ -2730,7 +2734,9 @@ void generate_prototype_implementation(IDL::Interface const& interface)
#if __has_include(<LibWeb/Bindings/@prototype_base_class@.h>)
# include <LibWeb/Bindings/@prototype_base_class@.h>
#endif
-#if __has_include(<LibWeb/CSS/@name@.h>)
+#if __has_include(<LibWeb/Crypto/@name@.h>)
+# include <LibWeb/Crypto/@name@.h>
+#elif __has_include(<LibWeb/CSS/@name@.h>)
# include <LibWeb/CSS/@name@.h>
#elif __has_include(<LibWeb/DOM/@name@.h>)
# include <LibWeb/DOM/@name@.h>
@@ -3179,7 +3185,9 @@ static void generate_iterator_header(IDL::Interface const& interface)
#include <LibWeb/Bindings/Wrapper.h>
// FIXME: This is very strange.
-#if __has_include(<LibWeb/CSS/@name@.h>)
+#if __has_include(<LibWeb/Crypto/@name@.h>)
+# include <LibWeb/Crypto/@name@.h>
+#elif __has_include(<LibWeb/CSS/@name@.h>)
# include <LibWeb/CSS/@name@.h>
#elif __has_include(<LibWeb/DOM/@name@.h>)
# include <LibWeb/DOM/@name@.h>
@@ -3356,7 +3364,9 @@ void generate_iterator_prototype_implementation(IDL::Interface const& interface)
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/WindowObject.h>
-#if __has_include(<LibWeb/CSS/@name@.h>)
+#if __has_include(<LibWeb/Crypto/@name@.h>)
+# include <LibWeb/Crypto/@name@.h>
+#elif __has_include(<LibWeb/CSS/@name@.h>)
# include <LibWeb/CSS/@name@.h>
#elif __has_include(<LibWeb/DOM/@name@.h>)
# include <LibWeb/DOM/@name@.h>
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()) {