diff --git a/AK/Random.cpp b/AK/Random.cpp index c4911052bce..c6f9df42a57 100644 --- a/AK/Random.cpp +++ b/AK/Random.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -89,6 +90,52 @@ u64 get_random_uniform_64(u64 max_bounds) return random_value % max_bounds; } +// https://w3c.github.io/webcrypto/#dfn-generate-a-random-uuid +String generate_random_uuid() +{ + // 1. Let bytes be a byte sequence of length 16. + u8 bytes[16]; + + // 2. Fill bytes with cryptographically secure random bytes. + fill_with_random(bytes); + + // 3. Set the 4 most significant bits of bytes[6], which represent the UUID version, to 0100. + bytes[6] = (bytes[6] & 0x0f) | 0x40; + + // 4. Set the 2 most significant bits of bytes[8], which represent the UUID variant, to 10. + bytes[8] = (bytes[8] & 0x3f) | 0x80; + + // 5. Return the string concatenation of « + // hexadecimal representation of bytes[0], + // hexadecimal representation of bytes[1], + // hexadecimal representation of bytes[2], + // hexadecimal representation of bytes[3], + // "-", + // hexadecimal representation of bytes[4], + // hexadecimal representation of bytes[5], + // "-", + // hexadecimal representation of bytes[6], + // hexadecimal representation of bytes[7], + // "-", + // hexadecimal representation of bytes[8], + // hexadecimal representation of bytes[9], + // "-", + // hexadecimal representation of bytes[10], + // hexadecimal representation of bytes[11], + // hexadecimal representation of bytes[12], + // hexadecimal representation of bytes[13], + // hexadecimal representation of bytes[14], + // hexadecimal representation of bytes[15] + // ». + return MUST(String::formatted( + "{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", + bytes[0], bytes[1], bytes[2], bytes[3], + bytes[4], bytes[5], + bytes[6], bytes[7], + bytes[8], bytes[9], + bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15])); +} + XorShift128PlusRNG::XorShift128PlusRNG() { // Splitmix64 is used as xorshift is sensitive to being seeded with all 0s diff --git a/AK/Random.h b/AK/Random.h index 6bd7449cfd4..e81f0227d0f 100644 --- a/AK/Random.h +++ b/AK/Random.h @@ -31,6 +31,8 @@ inline T get_random() u32 get_random_uniform(u32 max_bounds); u64 get_random_uniform_64(u64 max_bounds); +String generate_random_uuid(); + // http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf class XorShift128PlusRNG { public: @@ -58,6 +60,7 @@ inline void shuffle(Collection& collection) #if USING_AK_GLOBALLY using AK::fill_with_random; +using AK::generate_random_uuid; using AK::get_random; using AK::get_random_uniform; using AK::shuffle; diff --git a/Libraries/LibWeb/Crypto/Crypto.cpp b/Libraries/LibWeb/Crypto/Crypto.cpp index 4f1dbcc61cd..bf172497508 100644 --- a/Libraries/LibWeb/Crypto/Crypto.cpp +++ b/Libraries/LibWeb/Crypto/Crypto.cpp @@ -6,10 +6,8 @@ */ #include -#include #include #include -#include #include #include #include @@ -39,6 +37,12 @@ void Crypto::initialize(JS::Realm& realm) m_subtle = SubtleCrypto::create(realm); } +void Crypto::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_subtle); +} + GC::Ref Crypto::subtle() const { return *m_subtle; @@ -73,70 +77,15 @@ WebIDL::ExceptionOr> Crypto::get_random_values } // https://w3c.github.io/webcrypto/#dfn-Crypto-method-randomUUID -WebIDL::ExceptionOr Crypto::random_uuid() const +String Crypto::random_uuid() const { - auto& vm = realm().vm(); - - return TRY_OR_THROW_OOM(vm, generate_random_uuid()); -} - -void Crypto::visit_edges(Cell::Visitor& visitor) -{ - Base::visit_edges(visitor); - visitor.visit(m_subtle); + return generate_random_uuid(); } // https://w3c.github.io/webcrypto/#dfn-generate-a-random-uuid -ErrorOr generate_random_uuid() +String generate_random_uuid() { - // 1. Let bytes be a byte sequence of length 16. - u8 bytes[16]; - - // 2. Fill bytes with cryptographically secure random bytes. - fill_with_random(bytes); - - // 3. Set the 4 most significant bits of bytes[6], which represent the UUID version, to 0100. - bytes[6] &= ~(1 << 7); - bytes[6] |= 1 << 6; - bytes[6] &= ~(1 << 5); - bytes[6] &= ~(1 << 4); - - // 4. Set the 2 most significant bits of bytes[8], which represent the UUID variant, to 10. - bytes[8] |= 1 << 7; - bytes[8] &= ~(1 << 6); - - /* 5. Return the string concatenation of - « - hexadecimal representation of bytes[0], - hexadecimal representation of bytes[1], - hexadecimal representation of bytes[2], - hexadecimal representation of bytes[3], - "-", - hexadecimal representation of bytes[4], - hexadecimal representation of bytes[5], - "-", - hexadecimal representation of bytes[6], - hexadecimal representation of bytes[7], - "-", - hexadecimal representation of bytes[8], - hexadecimal representation of bytes[9], - "-", - hexadecimal representation of bytes[10], - hexadecimal representation of bytes[11], - hexadecimal representation of bytes[12], - hexadecimal representation of bytes[13], - hexadecimal representation of bytes[14], - hexadecimal representation of bytes[15] - ». - */ - StringBuilder builder; - TRY(builder.try_appendff("{:02x}{:02x}{:02x}{:02x}-", bytes[0], bytes[1], bytes[2], bytes[3])); - TRY(builder.try_appendff("{:02x}{:02x}-", bytes[4], bytes[5])); - TRY(builder.try_appendff("{:02x}{:02x}-", bytes[6], bytes[7])); - TRY(builder.try_appendff("{:02x}{:02x}-", bytes[8], bytes[9])); - TRY(builder.try_appendff("{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15])); - - return builder.to_string(); + return AK::generate_random_uuid(); } } diff --git a/Libraries/LibWeb/Crypto/Crypto.h b/Libraries/LibWeb/Crypto/Crypto.h index 0834d46cc77..d56ee34e445 100644 --- a/Libraries/LibWeb/Crypto/Crypto.h +++ b/Libraries/LibWeb/Crypto/Crypto.h @@ -25,7 +25,7 @@ public: GC::Ref subtle() const; WebIDL::ExceptionOr> get_random_values(GC::Root) const; - WebIDL::ExceptionOr random_uuid() const; + String random_uuid() const; protected: virtual void initialize(JS::Realm&) override; @@ -37,6 +37,6 @@ private: GC::Ptr m_subtle; }; -WEB_API ErrorOr generate_random_uuid(); +WEB_API String generate_random_uuid(); } diff --git a/Libraries/LibWeb/FileAPI/BlobURLStore.cpp b/Libraries/LibWeb/FileAPI/BlobURLStore.cpp index 78eaf453f82..73cd986d143 100644 --- a/Libraries/LibWeb/FileAPI/BlobURLStore.cpp +++ b/Libraries/LibWeb/FileAPI/BlobURLStore.cpp @@ -53,7 +53,7 @@ ErrorOr generate_new_blob_url() TRY(result.try_append('/')); // 9. Generate a UUID [RFC4122] as a string and append it to result. - auto uuid = TRY(Crypto::generate_random_uuid()); + auto uuid = Crypto::generate_random_uuid(); TRY(result.try_append(uuid)); // 10. Return result. diff --git a/Libraries/LibWeb/HTML/Navigable.cpp b/Libraries/LibWeb/HTML/Navigable.cpp index ab3e9d9b051..f4159d34e37 100644 --- a/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Libraries/LibWeb/HTML/Navigable.cpp @@ -1685,7 +1685,7 @@ void Navigable::begin_navigation(NavigateParams params) // NOTE: This step is handled in Navigable::navigate() // 7. Let navigationId be the result of generating a random UUID. - String navigation_id = MUST(Crypto::generate_random_uuid()); + auto navigation_id = Crypto::generate_random_uuid(); // FIXME: 8. If the surrounding agent is equal to navigable's active document's relevant agent, then continue these steps. // Otherwise, queue a global task on the navigation and traversal task source given navigable's active window to continue these steps. diff --git a/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp b/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp index 5fba7b02df3..7bf716e7276 100644 --- a/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp +++ b/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp @@ -25,8 +25,8 @@ void SessionHistoryEntry::visit_edges(Cell::Visitor& visitor) SessionHistoryEntry::SessionHistoryEntry() : m_classic_history_api_state(MUST(structured_serialize_for_storage(vm(), JS::js_null()))) , m_navigation_api_state(MUST(structured_serialize_for_storage(vm(), JS::js_undefined()))) - , m_navigation_api_key(MUST(Crypto::generate_random_uuid())) - , m_navigation_api_id(MUST(Crypto::generate_random_uuid())) + , m_navigation_api_key(Crypto::generate_random_uuid()) + , m_navigation_api_id(Crypto::generate_random_uuid()) { } diff --git a/Libraries/LibWeb/IndexedDB/IDBDatabase.cpp b/Libraries/LibWeb/IndexedDB/IDBDatabase.cpp index a2b7242e87e..25e7da80d9f 100644 --- a/Libraries/LibWeb/IndexedDB/IDBDatabase.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBDatabase.cpp @@ -21,8 +21,8 @@ IDBDatabase::IDBDatabase(JS::Realm& realm, Database& db) : EventTarget(realm) , m_name(db.name()) , m_associated_database(db) + , m_uuid(Crypto::generate_random_uuid()) { - m_uuid = MUST(Crypto::generate_random_uuid()); db.associate(*this); m_object_store_set = Vector> { db.object_stores() }; } diff --git a/Libraries/LibWeb/IndexedDB/IDBRequest.cpp b/Libraries/LibWeb/IndexedDB/IDBRequest.cpp index f8072f9a2d2..4192fe613dd 100644 --- a/Libraries/LibWeb/IndexedDB/IDBRequest.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBRequest.cpp @@ -25,8 +25,8 @@ IDBRequest::~IDBRequest() = default; IDBRequest::IDBRequest(JS::Realm& realm, IDBRequestSource source) : EventTarget(realm) , m_source(source) + , m_uuid(Crypto::generate_random_uuid()) { - m_uuid = MUST(Crypto::generate_random_uuid()); } void IDBRequest::initialize(JS::Realm& realm) diff --git a/Libraries/LibWeb/IndexedDB/IDBTransaction.cpp b/Libraries/LibWeb/IndexedDB/IDBTransaction.cpp index bf6c385b920..203ce28c186 100644 --- a/Libraries/LibWeb/IndexedDB/IDBTransaction.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBTransaction.cpp @@ -26,8 +26,8 @@ IDBTransaction::IDBTransaction(JS::Realm& realm, GC::Ref connection , m_mode(mode) , m_durability(durability) , m_scope(move(scopes)) + , m_uuid(Crypto::generate_random_uuid()) { - m_uuid = MUST(Crypto::generate_random_uuid()); connection->add_transaction(*this); } diff --git a/Libraries/LibWeb/WebDriver/Actions.cpp b/Libraries/LibWeb/WebDriver/Actions.cpp index b5ffa9f1254..08f4b53205d 100644 --- a/Libraries/LibWeb/WebDriver/Actions.cpp +++ b/Libraries/LibWeb/WebDriver/Actions.cpp @@ -1365,7 +1365,7 @@ GC_DEFINE_ALLOCATOR(ActionExecutor); void wait_for_an_action_queue_token(InputState& input_state) { // 1. Let token be a new unique identifier. - auto token = MUST(Crypto::generate_random_uuid()); + auto token = Crypto::generate_random_uuid(); // 2. Enqueue token in input state's actions queue. input_state.actions_queue.append(token); diff --git a/Libraries/LibWebView/ViewImplementation.cpp b/Libraries/LibWebView/ViewImplementation.cpp index ea580fd757f..6b4a19c0fc5 100644 --- a/Libraries/LibWebView/ViewImplementation.cpp +++ b/Libraries/LibWebView/ViewImplementation.cpp @@ -629,7 +629,7 @@ void ViewImplementation::initialize_client(CreateNewClient create_new_client) m_client_state.client->register_view(m_client_state.page_index, *this); } - m_client_state.client_handle = MUST(Web::Crypto::generate_random_uuid()); + m_client_state.client_handle = Web::Crypto::generate_random_uuid(); client().async_set_window_handle(m_client_state.page_index, m_client_state.client_handle); client().async_set_zoom_level(m_client_state.page_index, m_zoom_level); client().async_set_viewport(m_client_state.page_index, viewport_size(), m_device_pixel_ratio, m_is_fullscreen); diff --git a/Services/WebContent/WebDriverConnection.cpp b/Services/WebContent/WebDriverConnection.cpp index 7eee7906872..f26169c3cf9 100644 --- a/Services/WebContent/WebDriverConnection.cpp +++ b/Services/WebContent/WebDriverConnection.cpp @@ -1716,7 +1716,7 @@ Web::WebDriver::Response WebDriverConnection::element_click_impl(StringView elem }; // 3. Let input id be a the result of generating a UUID. - auto input_id = MUST(Web::Crypto::generate_random_uuid()); + auto input_id = Web::Crypto::generate_random_uuid(); // 4. Let source be the result of create an input source with input state, and "pointer". auto source = Web::WebDriver::create_input_source(input_state, Web::WebDriver::InputSourceType::Pointer, Web::WebDriver::PointerInputSource::Subtype::Mouse); @@ -2035,7 +2035,7 @@ Web::WebDriver::Response WebDriverConnection::element_send_keys_impl(StringView auto& input_state = Web::WebDriver::get_input_state(*current_top_level_browsing_context()); // 10. Let input id be a the result of generating a UUID. - auto input_id = MUST(Web::Crypto::generate_random_uuid()); + auto input_id = Web::Crypto::generate_random_uuid(); // 11. Let source be the result of create an input source with input state, and "key". auto source = Web::WebDriver::create_input_source(input_state, Web::WebDriver::InputSourceType::Key, {}); diff --git a/Services/WebDriver/Session.cpp b/Services/WebDriver/Session.cpp index 30700e964dc..58b0e977664 100644 --- a/Services/WebDriver/Session.cpp +++ b/Services/WebDriver/Session.cpp @@ -35,7 +35,7 @@ static HashMap> s_http_sessions; ErrorOr> Session::create(NonnullRefPtr client, JsonObject& capabilities, Web::WebDriver::SessionFlags flags) { // 1. Let session id be the result of generating a UUID. - auto session_id = MUST(Web::Crypto::generate_random_uuid()); + auto session_id = Web::Crypto::generate_random_uuid(); // 2. Let session be a new session with session ID session id, and HTTP flag flags contains "http". auto session = adopt_ref(*new Session(client, capabilities, move(session_id), flags));