2021-09-30 14:02:55 -03:00
/*
* Copyright ( c ) 2021 , Idan Horowitz < idan . horowitz @ serenityos . org >
2022-03-30 10:58:02 -03:00
* Copyright ( c ) 2022 , stelar7 < dudedbz @ gmail . com >
2021-09-30 14:02:55 -03:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include <AK/Random.h>
# include <LibJS/Runtime/TypedArray.h>
2026-04-18 05:54:06 -03:00
# include <LibWeb/Bindings/Crypto.h>
LibWeb: Remove unecessary dependence on Window from assorted classes
These classes only needed Window to get at its realm. Pass a realm
directly to construct Crypto, Encoding, HRT, IntersectionObserver,
NavigationTiming, Page, RequestIdleCallback, Selection, Streams, URL,
and XML classes.
2022-09-25 21:11:21 -03:00
# include <LibWeb/Bindings/Intrinsics.h>
2021-09-30 14:02:55 -03:00
# include <LibWeb/Crypto/Crypto.h>
2021-12-13 17:48:27 -03:00
# include <LibWeb/Crypto/SubtleCrypto.h>
2023-11-23 04:12:06 -03:00
# include <LibWeb/WebIDL/Buffers.h>
2025-12-26 10:36:14 -03:00
# include <LibWeb/WebIDL/QuotaExceededError.h>
2021-09-30 14:02:55 -03:00
namespace Web : : Crypto {
2024-11-14 12:01:23 -03:00
GC_DEFINE_ALLOCATOR ( Crypto ) ;
2023-11-19 15:47:52 -03:00
2024-11-14 12:01:23 -03:00
GC : : Ref < Crypto > Crypto : : create ( JS : : Realm & realm )
2022-09-04 08:15:05 -03:00
{
2024-11-13 13:50:17 -03:00
return realm . create < Crypto > ( realm ) ;
2022-09-04 08:15:05 -03:00
}
LibWeb: Remove unecessary dependence on Window from assorted classes
These classes only needed Window to get at its realm. Pass a realm
directly to construct Crypto, Encoding, HRT, IntersectionObserver,
NavigationTiming, Page, RequestIdleCallback, Selection, Streams, URL,
and XML classes.
2022-09-25 21:11:21 -03:00
Crypto : : Crypto ( JS : : Realm & realm )
: PlatformObject ( realm )
2022-09-04 08:15:05 -03:00
{
}
Crypto : : ~ Crypto ( ) = default ;
2023-08-07 03:41:28 -03:00
void Crypto : : initialize ( JS : : Realm & realm )
2021-12-13 17:48:27 -03:00
{
2024-03-16 09:13:08 -03:00
WEB_SET_PROTOTYPE_FOR_INTERFACE ( Crypto ) ;
2025-04-20 11:22:57 -03:00
Base : : initialize ( realm ) ;
2023-08-13 08:05:26 -03:00
m_subtle = SubtleCrypto : : create ( realm ) ;
2021-12-13 17:48:27 -03:00
}
2026-03-24 09:33:21 -03:00
void Crypto : : visit_edges ( Cell : : Visitor & visitor )
{
Base : : visit_edges ( visitor ) ;
visitor . visit ( m_subtle ) ;
}
2024-11-14 12:01:23 -03:00
GC : : Ref < SubtleCrypto > Crypto : : subtle ( ) const
2022-09-03 14:59:53 -03:00
{
return * m_subtle ;
}
2022-03-30 10:58:02 -03:00
// https://w3c.github.io/webcrypto/#dfn-Crypto-method-getRandomValues
2026-05-28 18:14:33 -03:00
WebIDL : : ExceptionOr < WebIDL : : ArrayBufferViewVariant > Crypto : : get_random_values ( WebIDL : : ArrayBufferViewVariant array ) const
2021-09-30 14:02:55 -03:00
{
2026-05-28 18:14:33 -03:00
WebIDL : : ArrayBufferView array_view { array } ;
2021-09-30 14:02:55 -03:00
// 1. If array is not an Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array, then throw a TypeMismatchError and terminate the algorithm.
2026-05-28 18:14:33 -03:00
auto typed_array = array_view . typed_array_base ( ) ;
if ( ! typed_array )
2025-08-07 20:31:52 -03:00
return WebIDL : : TypeMismatchError : : create ( realm ( ) , " array must be one of Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array " _utf16 ) ;
2021-09-30 14:02:55 -03:00
2026-05-28 18:14:33 -03:00
if ( ! typed_array - > element_name ( ) . is_one_of ( " Int8Array " sv , " Uint8Array " sv , " Uint8ClampedArray " sv , " Int16Array " sv , " Uint16Array " sv , " Int32Array " sv , " Uint32Array " sv , " BigInt64Array " sv , " BigUint64Array " sv ) )
2025-08-07 20:31:52 -03:00
return WebIDL : : TypeMismatchError : : create ( realm ( ) , " array must be one of Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array " _utf16 ) ;
2024-10-28 00:00:57 -03:00
2026-05-28 18:14:33 -03:00
auto typed_array_record = JS : : make_typed_array_with_buffer_witness_record ( * typed_array , JS : : ArrayBuffer : : Order : : SeqCst ) ;
2023-12-24 16:55:10 -03:00
// IMPLEMENTATION DEFINED: If the viewed array buffer is out-of-bounds, throw a InvalidStateError and terminate the algorithm.
if ( JS : : is_typed_array_out_of_bounds ( typed_array_record ) )
2025-08-07 20:31:52 -03:00
return WebIDL : : InvalidStateError : : create ( realm ( ) , Utf16String : : formatted ( JS : : ErrorType : : BufferOutOfBounds . format ( ) , " TypedArray " sv ) ) ;
2023-12-24 16:55:10 -03:00
2021-09-30 14:02:55 -03:00
// 2. If the byteLength of array is greater than 65536, throw a QuotaExceededError and terminate the algorithm.
2023-12-24 16:55:10 -03:00
if ( JS : : typed_array_byte_length ( typed_array_record ) > 65536 )
2025-08-07 20:31:52 -03:00
return WebIDL : : QuotaExceededError : : create ( realm ( ) , " array's byteLength may not be greater than 65536 " _utf16 ) ;
2021-09-30 14:02:55 -03:00
// 3. Overwrite all elements of array with cryptographically strong random values of the appropriate type.
2026-05-28 18:14:33 -03:00
fill_with_random ( array_view . viewed_array_buffer ( ) - > bytes ( ) . slice ( array_view . byte_offset ( ) , array_view . byte_length ( ) ) ) ;
2021-09-30 14:02:55 -03:00
// 4. Return array.
return array ;
}
2022-03-30 10:58:02 -03:00
// https://w3c.github.io/webcrypto/#dfn-Crypto-method-randomUUID
2026-03-24 09:33:21 -03:00
String Crypto : : random_uuid ( ) const
2022-03-30 10:58:02 -03:00
{
2026-03-24 09:33:21 -03:00
return generate_random_uuid ( ) ;
2023-03-13 10:22:07 -03:00
}
// https://w3c.github.io/webcrypto/#dfn-generate-a-random-uuid
2026-03-24 09:33:21 -03:00
String generate_random_uuid ( )
2023-03-13 10:22:07 -03:00
{
2026-03-24 09:33:21 -03:00
return AK : : generate_random_uuid ( ) ;
2023-07-07 23:48:11 -03:00
}
2022-09-12 20:23:28 -03:00
2021-09-30 14:02:55 -03:00
}