Produce JS-visible string results as UTF-16 at their source, including
numeric formatting, BigInt and BigFraction formatting, URI encoding,
console formatting, parser errors, regular expression errors, Intl and
Temporal records, LibUnicode locale boundaries, and LibWeb bindings.
Handle fractional radix formatting through the UTF-16 builder view.
Move the remaining LibJS primitive string users to UTF-16 views and
strings. Remove the primitive string UTF-8 accessors and byte-string
coercion paths so new callers cannot rely on the old storage model.
Build JSON.stringify, Date ISO strings, and Temporal string results with
Utf16StringBuilder when the result is consumed as a JavaScript string.
Keep UTF-8 conversion only at callers that explicitly need bytes outside
LibJS.
Problem: Crash when generating an RSA key — or serializing one —
whose publicExponent is a typed array whose backing ArrayBuffer has
been detached; for example, by calling transfer() on it.
Cause: Two places with big_integer_from_api_big_integer() reading the
bytes of the backing ArrayBuffer directly. But reading the bytes of a
detached buffer aborts.
Fix: Read the bytes with WebIDL get_buffer_source_copy() — which yields
an empty copy for a detached, or OOB resizable, buffer. The empty array
is already mapped to zero — so generation rejects the zero exponent with
an error, rather than crashing.
Fixes https://github.com/LadybirdBrowser/ladybird/issues/9991
Move owned ArrayBuffer and SharedArrayBuffer data blocks into the
ArrayBuffer heap partition. Keep unowned and host storage explicit, so
Wasm memory and external LibWeb buffers stay outside this partition.
Introduce DataBlock::OwnedBackingStore as the LibJS-owned byte storage
representation. Expose byte spans instead of a ByteBuffer object, giving
ArrayBuffer one allocation boundary that can later grow toward guarded
or caged storage.
Let callers that need ByteBuffer data copy from backing-store bytes.
Keep TransferArrayBuffer zero-copy by moving the DataBlock directly
instead of materializing a ByteBuffer in between.
Update the Wasm typed-array test helper to compare viewed byte ranges
after ArrayBuffer stops exposing ByteBuffer identity.
Enable -Wexit-time-destructors for all in-tree library targets and
update process-lifetime library statics so they no longer register
exit-time destructors. Long-lived caches, lookup tables, singleton
registries, and generated constants now use NeverDestroyed or leaked
references where the data is intended to live until process exit.
Update LibWeb, LibLine, and the binding generators so regenerated
sources follow the same rule instead of reintroducing destructed
statics.
CryptoKey structured serialization was cloning the internal algorithm
slot as a generic JS object. After deserialization, WebCrypto operations
such as exportKey() expected the slot to still be a native KeyAlgorithm
subclass and crashed when downcasting it.
Serialize the stored key algorithm with an explicit tag and reconstruct
the appropriate KeyAlgorithm subclass during deserialization. Also keep
EC private-key serialization aligned by encoding nested public keys as
EC public-key payloads rather than tagged top-level handles.
Represent BufferSource and ArrayBufferView as ordinary IDL typedefs over
their underlying union types, instead of special casing in the IDL
generator. This allows the union conversion/return machinery handle
these types consistently with other typedefs, which removes buffer
specific paths from the IDL generator.
This necessitates changing the WebIDL::BufferSource and
WebIDL::ArrayBufferView classes as views over these variants. This
replaces the old GC backed BufferableObject wrapper structure and
provide convenience helpers to determine things such as the byte length,
byte offset, backing buffer, and typed-array APIs.
Represent WebIDL C++ types with a single CppType model that tracks
nullability, optional presence, and contained storage.
GC-like values now use GC::Ref/GC::Ptr directly, while containers choose
"plain", "Root", or "Conservative" container types depending on what
they contain. For example, sequence<Element> becomes a RootVector of
GC::Ref values, while sequence<SomeDictionary> becomes a
ConservativeVector only when the dictionary contains GC-like values.
This moves the generated bindings away from wrapping GC values in
GC::Root by default.
This has broad fallout as the types passed to interfaces for GC
objects changes almost fully across the board.
Previously we were inconsistent by generating code for enum definitions
but not generating code for dictionaries. With future changes to the
IDL generator to expose helpers to convert to and from IDL values
this produced circular depdendencies. To solve this problem, also
generate the dictionary definitions in bindings headers.
Keep the JsonWebKey dictionary types in line with other dictionary
types in the codebase by putting them in the Crypto namespace
rather than under Web::Bindings.
Previously, the LibWeb bindings generator would output multiple per
interface files like Prototype/Constructor/Namespace/GlobalMixin
depending on the contents of that IDL file.
This complicates the build system as it means that it does not know
what files will be generated without knowledge of the contents of that
IDL file.
Instead, for each IDL file only generate a single Bindings/<IDLFile>.h
and Bindings/<IDLFile>.cpp.
For private key JWK imports, after decoding both d and x, derive
the public key from d and verify it matches x. A private key that
doesn't correspond to the provided public key doesn't "contain the
private key" as required by RFC 8037 Section 2.
After base64url-decoding the x and d fields during JWK import,
verify the decoded byte length matches the expected key size for
the curve (32 for Ed25519/X25519, 57 for Ed448, 56 for X448).
A truncated value does not "contain the public/private key" as
required by RFC 8037 Section 2.
Ed448 public keys are 57 bytes (456 bits), not 56 bytes (448 bits).
The curve is named "Ed448" after its 448-bit prime field, but per
RFC 8032 Section 5.2.5, the parameter b=456 and both private and
public keys are 57 bytes. This caused importKey to reject valid raw
Ed448 public keys with a DataError.
Note: The spec incorrectly says "not 448" for this check.
See https://github.com/w3c/webcrypto/pull/425#discussion_r3070135408
Refresh the imported wrapKey_unwrapKey WPT to the current upstream
version and treat the raw-secret and other raw* formats like raw
when wrap_key() and unwrap_key() serialize wrapped key bytes.
The updated test covers ChaCha20-Poly1305 wrapping with the
raw-secret format. Accepting the full set of byte-oriented raw
formats lets those keys round-trip through wrapKey and unwrapKey.
Keep the existing comment wording and wrapping where it already
matched the spec, but fix the places where wrap_key() and
unwrap_key() had drifted from the current wrapKey and unwrapKey
steps.
Add the missing realm and wrappedKey steps, use the spec terms
exportedKey, bytes, and key in the touched blocks, and leave
explicit FIXME comments for the queue-a-task and conversion
steps that we still skip.
Add a LibCrypto::Authentication::KMAC helper over OpenSSL.
Add keygen/import/export logic into WebCrypto.
Register KMAC128/KMAC256 operations with SubtleCrypto.
The WebCrypto spec was updated to normalize the algorithm before
getting a copy of the data bytes, and to queue a global task on the
crypto task source when rejecting or resolving the promise.
This fixes some WPT tests.
The WebCrypto spec was updated to normalize the algorithm before
getting a copy of the input bytes, and to queue a global task on the
crypto task source when rejecting or resolving the promise.
The WebCrypto spec was updated to normalize the algorithm before
getting a copy of the data bytes, and to queue a global task on the
crypto task source when rejecting or resolving the promise.
The error message incorrectly stated "encryption" when checking
for decrypt usage. Updated it to "decryption" for accuracy and
consistency with the operation being performed.
Implement AES-OCB AEAD using OpenSSL and expose it through
the WebCrypto API, including key management and AEAD parameters.
Add WPT:
/encrypt_decrypt/aes_ocb.tentative.https.any.html
While this does cost us an extra byte to serialize as it
contains _all_ interface names instead of the set of serializable
types, doing this will allow us to remove to use the same
enum for checking whether that interface is exposed in a future
commit.
The WebCrypto specification does not require the "alg" member
to be present when importing a symmetric JWK, as long as the
key material itself is valid.
Add tests covering JWK import without an "alg" field.
This fixes the following WPT:
WebCryptoAPI/import_export/ChaCha20-Poly1305_importKey
The key_ops vector is pre-sized with ensure_capacity(), so
bounds-checked append() is unnecessary here.
Switch to unchecked_append() to avoid redundant checks.
This change was suggested in a previous pull request #7563.
Add some typo and wrong comment.
Add a clang plugin check that flags GC::Cell subclasses (and their
base classes within the Cell hierarchy) that have destructors with
non-trivial bodies. Such logic should use Cell::finalize() instead.
Add GC_ALLOW_CELL_DESTRUCTOR annotation macro for opting out in
exceptional cases (currently only JS::Object).
This prevents us from accidentally adding code in destructors that
runs after something we're pointing to may have been destroyed.
(This could become a problem when the garbage collector sweeps
objects in an unfortunate order.)
This new check uncovered a handful of bugs which are then also fixed
in this commit. :^)
Implement ChaCha20-Poly1305 AEAD using OpenSSL and expose it through
the WebCrypto API, including key management and AEAD parameters.
Add WPT:
/encrypt_decrypt/chacha20_poly1305.tentative.https.any.worker.html
AK/Random is already the same as SecureRandom. See PR for more details.
ProcessPrng is used on Windows for compatibility w/ sandboxing measures
See e.g. https://crbug.com/40277768
Introduce a new SHAKE hash wrapper in LibCrypto backed by OpenSSL.
Wire cSHAKE128 and cSHAKE256 into WebCrypto.
Note that cSHAKE with non-empty functionName or customization is
currently rejected due to OpenSSL EVP limitations.
This fixes WPT:
WebCryptoAPI/digest/cshake.tentative.https.any.html