Skip to content

Commit

Permalink
LibWeb: Match algorithm names case-insensitive
Browse files Browse the repository at this point in the history
I dug through the code and the WebCryptoAPI spec to figure out the
reason for `... mixed case parameters` WPT tests and figured out that
our implementation was slightly wrong.

By being closer to the spec we can now pass those tests and also remove
a bunch of duplicated code.

Context: LadybirdBrowser#2598 (comment)
  • Loading branch information
devgianlu authored and awesomekling committed Nov 27, 2024
1 parent 6ebc812 commit 46e7247
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 139 deletions.
94 changes: 19 additions & 75 deletions Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,14 +314,9 @@ static WebIDL::ExceptionOr<ByteBuffer> generate_random_key(JS::VM& vm, u16 const

AlgorithmParams::~AlgorithmParams() = default;

JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AlgorithmParams::from_value(JS::VM& vm, JS::Value value)
JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AlgorithmParams::from_value(JS::VM&, JS::Value)
{
auto& object = value.as_object();

auto name = TRY(object.get("name"));
auto name_string = TRY(name.to_string(vm));

return adopt_own(*new AlgorithmParams { name_string });
return adopt_own(*new AlgorithmParams {});
}

AesCbcParams::~AesCbcParams() = default;
Expand All @@ -330,15 +325,12 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesCbcParams::from_value(J
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto iv_value = TRY(object.get("iv"));
if (!iv_value.is_object() || !(is<JS::TypedArrayBase>(iv_value.as_object()) || is<JS::ArrayBuffer>(iv_value.as_object()) || is<JS::DataView>(iv_value.as_object())))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
auto iv = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(iv_value.as_object()));

return adopt_own<AlgorithmParams>(*new AesCbcParams { name, iv });
return adopt_own<AlgorithmParams>(*new AesCbcParams { iv });
}

AesCtrParams::~AesCtrParams() = default;
Expand All @@ -347,9 +339,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesCtrParams::from_value(J
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto iv_value = TRY(object.get("counter"));
if (!iv_value.is_object() || !(is<JS::TypedArrayBase>(iv_value.as_object()) || is<JS::ArrayBuffer>(iv_value.as_object()) || is<JS::DataView>(iv_value.as_object())))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
Expand All @@ -358,7 +347,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesCtrParams::from_value(J
auto length_value = TRY(object.get("length"));
auto length = TRY(length_value.to_u8(vm));

return adopt_own<AlgorithmParams>(*new AesCtrParams { name, iv, length });
return adopt_own<AlgorithmParams>(*new AesCtrParams { iv, length });
}

AesGcmParams::~AesGcmParams() = default;
Expand All @@ -367,9 +356,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesGcmParams::from_value(J
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto iv_value = TRY(object.get("iv"));
if (!iv_value.is_object() || !(is<JS::TypedArrayBase>(iv_value.as_object()) || is<JS::ArrayBuffer>(iv_value.as_object()) || is<JS::DataView>(iv_value.as_object())))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
Expand All @@ -389,7 +375,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesGcmParams::from_value(J
maybe_tag_length = TRY(tag_length_value.to_u8(vm));
}

return adopt_own<AlgorithmParams>(*new AesGcmParams { name, iv, maybe_additional_data, maybe_tag_length });
return adopt_own<AlgorithmParams>(*new AesGcmParams { iv, maybe_additional_data, maybe_tag_length });
}

HKDFParams::~HKDFParams() = default;
Expand All @@ -398,9 +384,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> HKDFParams::from_value(JS:
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto hash_value = TRY(object.get("hash"));
auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value));

Expand All @@ -414,7 +397,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> HKDFParams::from_value(JS:
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
auto info = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(info_value.as_object()));

return adopt_own<AlgorithmParams>(*new HKDFParams { name, hash, salt, info });
return adopt_own<AlgorithmParams>(*new HKDFParams { hash, salt, info });
}

PBKDF2Params::~PBKDF2Params() = default;
Expand All @@ -423,9 +406,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> PBKDF2Params::from_value(J
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto salt_value = TRY(object.get("salt"));

if (!salt_value.is_object() || !(is<JS::TypedArrayBase>(salt_value.as_object()) || is<JS::ArrayBuffer>(salt_value.as_object()) || is<JS::DataView>(salt_value.as_object())))
Expand All @@ -439,7 +419,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> PBKDF2Params::from_value(J
auto hash_value = TRY(object.get("hash"));
auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value));

return adopt_own<AlgorithmParams>(*new PBKDF2Params { name, salt, iterations, hash });
return adopt_own<AlgorithmParams>(*new PBKDF2Params { salt, iterations, hash });
}

RsaKeyGenParams::~RsaKeyGenParams() = default;
Expand All @@ -448,9 +428,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaKeyGenParams::from_valu
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto modulus_length_value = TRY(object.get("modulusLength"));
auto modulus_length = TRY(modulus_length_value.to_u32(vm));

Expand All @@ -462,7 +439,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaKeyGenParams::from_valu

public_exponent = static_cast<JS::Uint8Array&>(public_exponent_value.as_object());

return adopt_own<AlgorithmParams>(*new RsaKeyGenParams { name, modulus_length, big_integer_from_api_big_integer(public_exponent) });
return adopt_own<AlgorithmParams>(*new RsaKeyGenParams { modulus_length, big_integer_from_api_big_integer(public_exponent) });
}

RsaHashedKeyGenParams::~RsaHashedKeyGenParams() = default;
Expand All @@ -471,9 +448,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaHashedKeyGenParams::fro
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto modulus_length_value = TRY(object.get("modulusLength"));
auto modulus_length = TRY(modulus_length_value.to_u32(vm));

Expand All @@ -488,7 +462,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaHashedKeyGenParams::fro
auto hash_value = TRY(object.get("hash"));
auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value));

return adopt_own<AlgorithmParams>(*new RsaHashedKeyGenParams { name, modulus_length, big_integer_from_api_big_integer(public_exponent), hash });
return adopt_own<AlgorithmParams>(*new RsaHashedKeyGenParams { modulus_length, big_integer_from_api_big_integer(public_exponent), hash });
}

RsaHashedImportParams::~RsaHashedImportParams() = default;
Expand All @@ -497,13 +471,10 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaHashedImportParams::fro
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto hash_value = TRY(object.get("hash"));
auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value));

return adopt_own<AlgorithmParams>(*new RsaHashedImportParams { name, hash });
return adopt_own<AlgorithmParams>(*new RsaHashedImportParams { hash });
}

RsaOaepParams::~RsaOaepParams() = default;
Expand All @@ -512,9 +483,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaOaepParams::from_value(
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto label_value = TRY(object.get("label"));

ByteBuffer label;
Expand All @@ -525,7 +493,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaOaepParams::from_value(
label = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(label_value.as_object()));
}

return adopt_own<AlgorithmParams>(*new RsaOaepParams { name, move(label) });
return adopt_own<AlgorithmParams>(*new RsaOaepParams { move(label) });
}

EcdsaParams::~EcdsaParams() = default;
Expand All @@ -534,13 +502,10 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> EcdsaParams::from_value(JS
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto hash_value = TRY(object.get("hash"));
auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value));

return adopt_own<AlgorithmParams>(*new EcdsaParams { name, hash });
return adopt_own<AlgorithmParams>(*new EcdsaParams { hash });
}

EcKeyGenParams::~EcKeyGenParams() = default;
Expand All @@ -549,13 +514,10 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> EcKeyGenParams::from_value
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto curve_value = TRY(object.get("namedCurve"));
auto curve = TRY(curve_value.to_string(vm));

return adopt_own<AlgorithmParams>(*new EcKeyGenParams { name, curve });
return adopt_own<AlgorithmParams>(*new EcKeyGenParams { curve });
}

AesKeyGenParams::~AesKeyGenParams() = default;
Expand All @@ -564,13 +526,10 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesKeyGenParams::from_valu
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto length_value = TRY(object.get("length"));
auto length = TRY(length_value.to_u16(vm));

return adopt_own<AlgorithmParams>(*new AesKeyGenParams { name, length });
return adopt_own<AlgorithmParams>(*new AesKeyGenParams { length });
}

AesDerivedKeyParams::~AesDerivedKeyParams() = default;
Expand All @@ -579,13 +538,10 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesDerivedKeyParams::from_
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto length_value = TRY(object.get("length"));
auto length = TRY(length_value.to_u16(vm));

return adopt_own<AlgorithmParams>(*new AesDerivedKeyParams { name, length });
return adopt_own<AlgorithmParams>(*new AesDerivedKeyParams { length });
}

EcdhKeyDeriveParams::~EcdhKeyDeriveParams() = default;
Expand All @@ -594,9 +550,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> EcdhKeyDeriveParams::from_
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto key_value = TRY(object.get("public"));
auto key_object = TRY(key_value.to_object(vm));

Expand All @@ -606,7 +559,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> EcdhKeyDeriveParams::from_

auto& key = verify_cast<CryptoKey>(*key_object);

return adopt_own<AlgorithmParams>(*new EcdhKeyDeriveParams { name, key });
return adopt_own<AlgorithmParams>(*new EcdhKeyDeriveParams { key });
}

EcKeyImportParams::~EcKeyImportParams() = default;
Expand All @@ -615,13 +568,10 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> EcKeyImportParams::from_va
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto named_curve_value = TRY(object.get("namedCurve"));
auto named_curve = TRY(named_curve_value.to_string(vm));

return adopt_own<AlgorithmParams>(*new EcKeyImportParams { name, named_curve });
return adopt_own<AlgorithmParams>(*new EcKeyImportParams { named_curve });
}

HmacImportParams::~HmacImportParams() = default;
Expand All @@ -630,9 +580,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> HmacImportParams::from_val
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto hash_value = TRY(object.get("hash"));
auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value));

Expand All @@ -642,7 +589,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> HmacImportParams::from_val
maybe_length = TRY(length_value.to_u32(vm));
}

return adopt_own<AlgorithmParams>(*new HmacImportParams { name, hash, maybe_length });
return adopt_own<AlgorithmParams>(*new HmacImportParams { hash, maybe_length });
}

HmacKeyGenParams::~HmacKeyGenParams() = default;
Expand All @@ -651,9 +598,6 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> HmacKeyGenParams::from_val
{
auto& object = value.as_object();

auto name_value = TRY(object.get("name"));
auto name = TRY(name_value.to_string(vm));

auto hash_value = TRY(object.get("hash"));
auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value));

Expand All @@ -663,7 +607,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> HmacKeyGenParams::from_val
maybe_length = TRY(length_value.to_u32(vm));
}

return adopt_own<AlgorithmParams>(*new HmacKeyGenParams { name, hash, maybe_length });
return adopt_own<AlgorithmParams>(*new HmacKeyGenParams { hash, maybe_length });
}

// https://w3c.github.io/webcrypto/#rsa-oaep-operations
Expand Down
Loading

0 comments on commit 46e7247

Please sign in to comment.