Compare commits

..

1 commit

Author SHA1 Message Date
Saksham Goyal
2f2194cee3
Merge 19551bfce5 into d6bcd3fb0b 2024-11-20 20:01:46 -05:00
34 changed files with 112 additions and 1671 deletions

View file

@ -35,5 +35,5 @@ you are welcome to ask on [Discord](../README.md#get-in-touch-and-participate).
* [LibWeb: From Loading to Painting](LibWebFromLoadingToPainting.md)
* [LibWeb: Browsing Contexts and Navigables](BrowsingContextsAndNavigables.md)
* [How to Add an IDL File](AddNewIDLFile.md)
* [LibWeb Code Style & Patterns](LibWebPatterns.md)
* [LibWeb Code Style & Patterns](Browser/Patterns.md)
* [CSS Generated Files](CSSGeneratedFiles.md)

View file

@ -15,8 +15,6 @@
# include <sys/disk.h>
#elif defined(AK_OS_LINUX)
# include <linux/fs.h>
#elif defined(AK_OS_WINDOWS)
# include <dirent.h>
#endif
// On Linux distros that use glibc `basename` is defined as a macro that expands to `__xpg_basename`, so we undefine it

View file

@ -400,8 +400,7 @@ public:
constexpr Color with_opacity(float opacity) const
{
VERIFY(opacity >= 0 && opacity <= 1);
return with_alpha(static_cast<u8>(round(alpha() * opacity)));
return with_alpha(alpha() * opacity);
}
constexpr Color darkened(float amount = 0.5f) const
@ -550,9 +549,9 @@ public:
break;
}
auto out_r = static_cast<u8>(round(r * 255));
auto out_g = static_cast<u8>(round(g * 255));
auto out_b = static_cast<u8>(round(b * 255));
u8 out_r = (u8)(r * 255);
u8 out_g = (u8)(g * 255);
u8 out_b = (u8)(b * 255);
return Color(out_r, out_g, out_b);
}

View file

@ -102,13 +102,8 @@ Optional<StyleProperty> PropertyOwningCSSStyleDeclaration::property(PropertyID p
}
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-setproperty
WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(StringView property_name, StringView value, StringView priority)
WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(PropertyID property_id, StringView value, StringView priority)
{
auto maybe_property_id = property_id_from_string(property_name);
if (!maybe_property_id.has_value())
return {};
auto property_id = maybe_property_id.value();
// 1. If the computed flag is set, then throw a NoModificationAllowedError exception.
// NOTE: This is handled by the virtual override in ResolvedCSSStyleDeclaration.
@ -119,7 +114,7 @@ WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(String
// 3. If value is the empty string, invoke removeProperty() with property as argument and return.
if (value.is_empty()) {
MUST(remove_property(property_name));
MUST(remove_property(property_id));
return {};
}
@ -151,22 +146,10 @@ WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(String
}
// 9. Otherwise,
else {
if (property_id == PropertyID::Custom) {
auto custom_name = FlyString::from_utf8_without_validation(property_name.bytes());
StyleProperty style_property {
.important = !priority.is_empty() ? Important::Yes : Important::No,
.property_id = property_id,
.value = component_value_list.release_nonnull(),
.custom_name = custom_name,
};
m_custom_properties.set(custom_name, style_property);
updated = true;
} else {
// let updated be the result of set the CSS declaration property with value component value list,
// with the important flag set if priority is not the empty string, and unset otherwise,
// and with the list of declarations being the declarations.
updated = set_a_css_declaration(property_id, *component_value_list, !priority.is_empty() ? Important::Yes : Important::No);
}
// let updated be the result of set the CSS declaration property with value component value list,
// with the important flag set if priority is not the empty string, and unset otherwise,
// and with the list of declarations being the declarations.
updated = set_a_css_declaration(property_id, *component_value_list, !priority.is_empty() ? Important::Yes : Important::No);
}
// 10. If updated is true, update style attribute for the CSS declaration block.
@ -177,12 +160,8 @@ WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_property(String
}
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty
WebIDL::ExceptionOr<String> PropertyOwningCSSStyleDeclaration::remove_property(StringView property_name)
WebIDL::ExceptionOr<String> PropertyOwningCSSStyleDeclaration::remove_property(PropertyID property_id)
{
auto property_id = property_id_from_string(property_name);
if (!property_id.has_value())
return String {};
// 1. If the computed flag is set, then throw a NoModificationAllowedError exception.
// NOTE: This is handled by the virtual override in ResolvedCSSStyleDeclaration.
@ -190,7 +169,8 @@ WebIDL::ExceptionOr<String> PropertyOwningCSSStyleDeclaration::remove_property(S
// NOTE: We've already converted it to a PropertyID enum value.
// 3. Let value be the return value of invoking getPropertyValue() with property as argument.
auto value = get_property_value(property_name);
// FIXME: The trip through string_from_property_id() here is silly.
auto value = get_property_value(string_from_property_id(property_id));
// 4. Let removed be false.
bool removed = false;
@ -200,12 +180,7 @@ WebIDL::ExceptionOr<String> PropertyOwningCSSStyleDeclaration::remove_property(S
// 2. Remove that CSS declaration and let removed be true.
// 6. Otherwise, if property is a case-sensitive match for a property name of a CSS declaration in the declarations, remove that CSS declaration and let removed be true.
if (property_id == PropertyID::Custom) {
auto custom_name = FlyString::from_utf8_without_validation(property_name.bytes());
removed = m_custom_properties.remove(custom_name);
} else {
removed = m_properties.remove_first_matching([&](auto& entry) { return entry.property_id == property_id; });
}
removed = m_properties.remove_first_matching([&](auto& entry) { return entry.property_id == property_id; });
// 7. If removed is true, Update style attribute for the CSS declaration block.
if (removed)
@ -266,14 +241,6 @@ String CSSStyleDeclaration::get_property_value(StringView property_name) const
if (!property_id.has_value())
return {};
if (property_id.value() == PropertyID::Custom) {
auto maybe_custom_property = custom_property(FlyString::from_utf8_without_validation(property_name.bytes()));
if (maybe_custom_property.has_value()) {
return maybe_custom_property.value().value->to_string();
}
return {};
}
// 2. If property is a shorthand property, then follow these substeps:
if (property_is_shorthand(property_id.value())) {
// 1. Let list be a new empty array.
@ -318,26 +285,26 @@ StringView CSSStyleDeclaration::get_property_priority(StringView property_name)
auto property_id = property_id_from_string(property_name);
if (!property_id.has_value())
return {};
if (property_id.value() == PropertyID::Custom) {
auto maybe_custom_property = custom_property(FlyString::from_utf8_without_validation(property_name.bytes()));
if (!maybe_custom_property.has_value())
return {};
return maybe_custom_property.value().important == Important::Yes ? "important"sv : ""sv;
}
auto maybe_property = property(property_id.value());
if (!maybe_property.has_value())
return {};
return maybe_property->important == Important::Yes ? "important"sv : ""sv;
}
WebIDL::ExceptionOr<void> CSSStyleDeclaration::set_property(PropertyID property_id, StringView css_text, StringView priority)
WebIDL::ExceptionOr<void> CSSStyleDeclaration::set_property(StringView property_name, StringView css_text, StringView priority)
{
return set_property(string_from_property_id(property_id), css_text, priority);
auto property_id = property_id_from_string(property_name);
if (!property_id.has_value())
return {};
return set_property(property_id.value(), css_text, priority);
}
WebIDL::ExceptionOr<String> CSSStyleDeclaration::remove_property(PropertyID property_name)
WebIDL::ExceptionOr<String> CSSStyleDeclaration::remove_property(StringView property_name)
{
return remove_property(string_from_property_id(property_name));
auto property_id = property_id_from_string(property_name);
if (!property_id.has_value())
return String {};
return remove_property(property_id.value());
}
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext

View file

@ -29,13 +29,12 @@ public:
virtual String item(size_t index) const = 0;
virtual Optional<StyleProperty> property(PropertyID) const = 0;
virtual Optional<StyleProperty> custom_property(FlyString const& custom_property_name) const = 0;
virtual WebIDL::ExceptionOr<void> set_property(PropertyID, StringView css_text, StringView priority = ""sv);
virtual WebIDL::ExceptionOr<String> remove_property(PropertyID);
virtual WebIDL::ExceptionOr<void> set_property(PropertyID, StringView css_text, StringView priority = ""sv) = 0;
virtual WebIDL::ExceptionOr<String> remove_property(PropertyID) = 0;
virtual WebIDL::ExceptionOr<void> set_property(StringView property_name, StringView css_text, StringView priority) = 0;
virtual WebIDL::ExceptionOr<String> remove_property(StringView property_name) = 0;
virtual WebIDL::ExceptionOr<void> set_property(StringView property_name, StringView css_text, StringView priority);
virtual WebIDL::ExceptionOr<String> remove_property(StringView property_name);
String get_property_value(StringView property) const;
StringView get_property_priority(StringView property) const;
@ -76,13 +75,13 @@ public:
virtual String item(size_t index) const override;
virtual Optional<StyleProperty> property(PropertyID) const override;
virtual Optional<StyleProperty> custom_property(FlyString const& custom_property_name) const override { return m_custom_properties.get(custom_property_name); }
virtual WebIDL::ExceptionOr<void> set_property(StringView property_name, StringView css_text, StringView priority) override;
virtual WebIDL::ExceptionOr<String> remove_property(StringView property_name) override;
virtual WebIDL::ExceptionOr<void> set_property(PropertyID, StringView css_text, StringView priority) override;
virtual WebIDL::ExceptionOr<String> remove_property(PropertyID) override;
Vector<StyleProperty> const& properties() const { return m_properties; }
HashMap<FlyString, StyleProperty> const& custom_properties() const { return m_custom_properties; }
Optional<StyleProperty> custom_property(FlyString const& custom_property_name) const { return m_custom_properties.get(custom_property_name); }
size_t custom_property_count() const { return m_custom_properties.size(); }
virtual String serialized() const final override;

View file

@ -601,12 +601,6 @@ Optional<StyleProperty> ResolvedCSSStyleDeclaration::property(PropertyID propert
};
}
Optional<StyleProperty> ResolvedCSSStyleDeclaration::custom_property(FlyString const&) const
{
dbgln("FIXME: ResolvedCSSStyleDeclaration::custom_property is not implemented");
return {};
}
static WebIDL::ExceptionOr<void> cannot_modify_computed_property_error(JS::Realm& realm)
{
return WebIDL::NoModificationAllowedError::create(realm, "Cannot modify properties in result of getComputedStyle()"_string);

View file

@ -24,7 +24,6 @@ public:
virtual String item(size_t index) const override;
virtual Optional<StyleProperty> property(PropertyID) const override;
virtual Optional<StyleProperty> custom_property(FlyString const& custom_property_name) const override;
virtual WebIDL::ExceptionOr<void> set_property(PropertyID, StringView css_text, StringView priority) override;
virtual WebIDL::ExceptionOr<void> set_property(StringView property_name, StringView css_text, StringView priority) override;
virtual WebIDL::ExceptionOr<String> remove_property(PropertyID) override;

View file

@ -45,7 +45,7 @@ ValueComparingNonnullRefPtr<CSSColorValue> CSSColorValue::create_from_color(Colo
return make_rgb_color(color);
}
Optional<double> CSSColorValue::resolve_hue(CSSStyleValue const& style_value)
Optional<float> CSSColorValue::resolve_hue(CSSStyleValue const& style_value)
{
// <number> | <angle> | none
auto normalized = [](double number) {
@ -67,11 +67,11 @@ Optional<double> CSSColorValue::resolve_hue(CSSStyleValue const& style_value)
return {};
}
Optional<double> CSSColorValue::resolve_with_reference_value(CSSStyleValue const& style_value, float one_hundred_percent_value)
Optional<float> CSSColorValue::resolve_with_reference_value(CSSStyleValue const& style_value, float one_hundred_percent_value)
{
// <percentage> | <number> | none
auto normalize_percentage = [one_hundred_percent_value](Percentage const& percentage) {
return percentage.as_fraction() * one_hundred_percent_value;
return static_cast<float>(percentage.as_fraction()) * one_hundred_percent_value;
};
if (style_value.is_percentage())
@ -94,7 +94,7 @@ Optional<double> CSSColorValue::resolve_with_reference_value(CSSStyleValue const
return {};
}
Optional<double> CSSColorValue::resolve_alpha(CSSStyleValue const& style_value)
Optional<float> CSSColorValue::resolve_alpha(CSSStyleValue const& style_value)
{
// <number> | <percentage> | none
auto normalized = [](double number) {

View file

@ -48,9 +48,9 @@ protected:
{
}
static Optional<double> resolve_hue(CSSStyleValue const&);
static Optional<double> resolve_with_reference_value(CSSStyleValue const&, float one_hundred_percent_value);
static Optional<double> resolve_alpha(CSSStyleValue const&);
static Optional<float> resolve_hue(CSSStyleValue const&);
static Optional<float> resolve_with_reference_value(CSSStyleValue const&, float one_hundred_percent_value);
static Optional<float> resolve_alpha(CSSStyleValue const&);
private:
ColorType m_color_type;

View file

@ -25,8 +25,8 @@ Color CSSHWB::to_color(Optional<Layout::NodeWithStyle const&>) const
return Color(gray, gray, gray, to_byte(alpha_val));
}
auto value = 1 - b_val;
auto saturation = 1 - (w_val / value);
float value = 1 - b_val;
float saturation = 1 - (w_val / value);
return Color::from_hsv(h_val, saturation, value).with_opacity(alpha_val);
}

View file

@ -2526,106 +2526,6 @@ WebIDL::ExceptionOr<JS::Value> ECDSA::verify(AlgorithmParams const& params, GC::
return JS::Value(result);
}
// https://w3c.github.io/webcrypto/#ecdh-operations
WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> ECDH::generate_key(AlgorithmParams const& params, bool extractable, Vector<Bindings::KeyUsage> const& key_usages)
{
// 1. If usages contains an entry which is not "deriveKey" or "deriveBits" then throw a SyntaxError.
for (auto const& usage : key_usages) {
if (usage != Bindings::KeyUsage::Derivekey && usage != Bindings::KeyUsage::Derivebits) {
return WebIDL::SyntaxError::create(m_realm, MUST(String::formatted("Invalid key usage '{}'", idl_enum_to_string(usage))));
}
}
auto const& normalized_algorithm = static_cast<EcKeyGenParams const&>(params);
// 2. If the namedCurve member of normalizedAlgorithm is "P-256", "P-384" or "P-521":
// Generate an Elliptic Curve key pair, as defined in [RFC6090]
// with domain parameters for the curve identified by the namedCurve member of normalizedAlgorithm.
Variant<Empty, ::Crypto::Curves::SECP256r1, ::Crypto::Curves::SECP384r1> curve;
if (normalized_algorithm.named_curve.is_one_of("P-256"sv, "P-384"sv, "P-521"sv)) {
if (normalized_algorithm.named_curve.equals_ignoring_ascii_case("P-256"sv))
curve = ::Crypto::Curves::SECP256r1 {};
if (normalized_algorithm.named_curve.equals_ignoring_ascii_case("P-384"sv))
curve = ::Crypto::Curves::SECP384r1 {};
// FIXME: Support P-521
if (normalized_algorithm.named_curve.equals_ignoring_ascii_case("P-521"sv))
return WebIDL::NotSupportedError::create(m_realm, "'P-521' is not supported yet"_string);
} else {
// If the namedCurve member of normalizedAlgorithm is a value specified in an applicable specification
// that specifies the use of that value with ECDH:
// Perform the ECDH generation steps specified in that specification,
// passing in normalizedAlgorithm and resulting in an elliptic curve key pair.
// Otherwise: throw a NotSupportedError
return WebIDL::NotSupportedError::create(m_realm, "Only 'P-256', 'P-384' and 'P-521' is supported"_string);
}
// 3. If performing the operation results in an error, then throw a OperationError.
auto maybe_private_key_data = curve.visit(
[](Empty const&) -> ErrorOr<ByteBuffer> { return Error::from_string_literal("noop error"); },
[](auto instance) { return instance.generate_private_key(); });
if (maybe_private_key_data.is_error())
return WebIDL::OperationError::create(m_realm, "Failed to create valid crypto instance"_string);
auto private_key_data = maybe_private_key_data.release_value();
auto maybe_public_key_data = curve.visit(
[](Empty const&) -> ErrorOr<ByteBuffer> { return Error::from_string_literal("noop error"); },
[&](auto instance) { return instance.generate_public_key(private_key_data); });
if (maybe_public_key_data.is_error())
return WebIDL::OperationError::create(m_realm, "Failed to create valid crypto instance"_string);
auto public_key_data = maybe_public_key_data.release_value();
// 4. Let algorithm be a new EcKeyAlgorithm object.
auto algorithm = EcKeyAlgorithm::create(m_realm);
// 5. Set the name attribute of algorithm to "ECDH".
algorithm->set_name("ECDH"_string);
// 6. Set the namedCurve attribute of algorithm to equal the namedCurve member of normalizedAlgorithm.
algorithm->set_named_curve(normalized_algorithm.named_curve);
// 7. Let publicKey be a new CryptoKey representing the public key of the generated key pair.
auto public_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { public_key_data });
// 8. Set the [[type]] internal slot of publicKey to "public"
public_key->set_type(Bindings::KeyType::Public);
// 9. Set the [[algorithm]] internal slot of publicKey to algorithm.
public_key->set_algorithm(algorithm);
// 10. Set the [[extractable]] internal slot of publicKey to true.
public_key->set_extractable(true);
// 11. Set the [[usages]] internal slot of publicKey to be the empty list.
public_key->set_usages({});
// 12. Let privateKey be a new CryptoKey representing the private key of the generated key pair.
auto private_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { private_key_data });
// 13. Set the [[type]] internal slot of privateKey to "private"
private_key->set_type(Bindings::KeyType::Private);
// 14. Set the [[algorithm]] internal slot of privateKey to algorithm.
private_key->set_algorithm(algorithm);
// 15. Set the [[extractable]] internal slot of privateKey to extractable.
private_key->set_extractable(extractable);
// 16. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "deriveKey", "deriveBits" ].
private_key->set_usages(usage_intersection(key_usages, { { Bindings::KeyUsage::Derivekey, Bindings::KeyUsage::Derivebits } }));
// 17. Let result be a new CryptoKeyPair dictionary.
// 18. Set the publicKey attribute of result to be publicKey.
// 19. Set the privateKey attribute of result to be privateKey.
// 20. Return the result of converting result to an ECMAScript Object, as defined by [WebIDL].
return Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>> { CryptoKeyPair::create(m_realm, public_key, private_key) };
}
// https://wicg.github.io/webcrypto-secure-curves/#ed25519-operations
WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> ED25519::generate_key([[maybe_unused]] AlgorithmParams const& params, bool extractable, Vector<Bindings::KeyUsage> const& key_usages)
{

View file

@ -493,22 +493,6 @@ private:
}
};
class ECDH : public AlgorithmMethods {
public:
virtual WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
// TODO: virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, GC::Ref<CryptoKey>, Optional<u32>) override;
// TODO: virtual WebIDL::ExceptionOr<GC::Ref<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
// TODO: virtual WebIDL::ExceptionOr<GC::Ref<JS::Object>> export_key(Bindings::KeyFormat, GC::Ref<CryptoKey>) override;
static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ECDH(realm)); }
private:
explicit ECDH(JS::Realm& realm)
: AlgorithmMethods(realm)
{
}
};
class ED25519 : public AlgorithmMethods {
public:
virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> sign(AlgorithmParams const&, GC::Ref<CryptoKey>, ByteBuffer const&) override;

View file

@ -801,10 +801,10 @@ SupportedAlgorithmsMap supported_algorithms()
// FIXME: define_an_algorithm<ECDSA>("exportKey"_string, "ECDSA"_string);
// https://w3c.github.io/webcrypto/#ecdh-registration
// FIXME: define_an_algorithm<ECDH, EcKeyGenParams>("generateKey"_string, "ECDH"_string);
// FIXME: define_an_algorithm<ECDH, EcdhKeyDerivePrams>("deriveBits"_string, "ECDH"_string);
// FIXME: define_an_algorithm<ECDH, EcKeyImportParams>("importKey"_string, "ECDH"_string);
// FIXME: define_an_algorithm<ECDH>("exportKey"_string, "ECDH"_string);
define_an_algorithm<ECDH, EcKeyGenParams>("generateKey"_string, "ECDH"_string);
// https://w3c.github.io/webcrypto/#aes-ctr-registration
define_an_algorithm<AesCtr, AesCtrParams>("encrypt"_string, "AES-CTR"_string);

View file

@ -177,6 +177,8 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
if (!m_navigable->active_document()->is_fully_active())
return EventResult::Dropped;
auto position = viewport_position;
m_navigable->active_document()->update_layout();
if (!paint_root())
@ -188,20 +190,20 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
auto handled_event = EventResult::Dropped;
GC::Ptr<Painting::Paintable> paintable;
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
if (auto result = target_for_mouse_position(position); result.has_value())
paintable = result->paintable;
if (paintable) {
auto* containing_block = paintable->containing_block();
while (containing_block) {
auto handled_scroll_event = containing_block->handle_mousewheel({}, viewport_position, buttons, modifiers, wheel_delta_x, wheel_delta_y);
auto handled_scroll_event = containing_block->handle_mousewheel({}, position, buttons, modifiers, wheel_delta_x, wheel_delta_y);
if (handled_scroll_event)
return EventResult::Handled;
containing_block = containing_block->containing_block();
}
if (paintable->handle_mousewheel({}, viewport_position, buttons, modifiers, wheel_delta_x, wheel_delta_y))
if (paintable->handle_mousewheel({}, position, buttons, modifiers, wheel_delta_x, wheel_delta_y))
return EventResult::Handled;
auto node = dom_node_for_event_dispatch(*paintable);
@ -210,7 +212,7 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
// FIXME: Support wheel events in nested browsing contexts.
if (is<HTML::HTMLIFrameElement>(*node)) {
auto& iframe = static_cast<HTML::HTMLIFrameElement&>(*node);
auto position_in_iframe = viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node()));
auto position_in_iframe = position.translated(compute_mouse_event_offset({}, paintable->layout_node()));
iframe.content_navigable()->event_handler().handle_mousewheel(position_in_iframe, screen_position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y);
return EventResult::Dropped;
}
@ -220,9 +222,10 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
return EventResult::Dropped;
auto page_offset = compute_mouse_event_page_offset(viewport_position);
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
if (node->dispatch_event(UIEvents::WheelEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::wheel, screen_position, page_offset, viewport_position, offset, wheel_delta_x, wheel_delta_y, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors())) {
auto offset = compute_mouse_event_offset(position, *layout_node);
auto client_offset = compute_mouse_event_client_offset(position);
auto page_offset = compute_mouse_event_page_offset(client_offset);
if (node->dispatch_event(UIEvents::WheelEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::wheel, screen_position, page_offset, client_offset, offset, wheel_delta_x, wheel_delta_y, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors())) {
m_navigable->active_window()->scroll_by(wheel_delta_x, wheel_delta_y);
}
@ -243,24 +246,26 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
if (!m_navigable->active_document()->is_fully_active())
return EventResult::Dropped;
auto position = viewport_position;
m_navigable->active_document()->update_layout();
if (!paint_root())
return EventResult::Dropped;
GC::Ptr<Painting::Paintable> paintable;
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
if (auto result = target_for_mouse_position(position); result.has_value())
paintable = result->paintable;
if (paintable && paintable->wants_mouse_events()) {
if (paintable->handle_mouseup({}, viewport_position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
if (paintable->handle_mouseup({}, position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
return EventResult::Cancelled;
// Things may have changed as a consequence of Layout::Node::handle_mouseup(). Hit test again.
if (!paint_root())
return EventResult::Handled;
if (auto result = paint_root()->hit_test(viewport_position, Painting::HitTestType::Exact); result.has_value())
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::Exact); result.has_value())
paintable = result->paintable;
}
@ -272,7 +277,7 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
if (node) {
if (is<HTML::HTMLIFrameElement>(*node)) {
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
return content_navigable->event_handler().handle_mouseup(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
return content_navigable->event_handler().handle_mouseup(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
return EventResult::Dropped;
}
@ -285,21 +290,22 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
goto after_node_use;
}
auto page_offset = compute_mouse_event_page_offset(viewport_position);
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mouseup, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
auto offset = compute_mouse_event_offset(position, *layout_node);
auto client_offset = compute_mouse_event_client_offset(position);
auto page_offset = compute_mouse_event_page_offset(client_offset);
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mouseup, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
handled_event = EventResult::Handled;
bool run_activation_behavior = false;
if (node.ptr() == m_mousedown_target) {
if (button == UIEvents::MouseButton::Primary) {
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::click, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::click, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
} else if (button == UIEvents::MouseButton::Middle) {
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::auxclick, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::auxclick, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
} else if (button == UIEvents::MouseButton::Secondary) {
// Allow the user to bypass custom context menus by holding shift, like Firefox.
if ((modifiers & UIEvents::Mod_Shift) == 0)
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::contextmenu, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::contextmenu, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
else
run_activation_behavior = true;
}
@ -372,6 +378,8 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
if (!m_navigable->active_document()->is_fully_active())
return EventResult::Dropped;
auto position = viewport_position;
m_navigable->active_document()->update_layout();
if (!paint_root())
@ -382,7 +390,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
{
GC::Ptr<Painting::Paintable> paintable;
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
if (auto result = target_for_mouse_position(position); result.has_value())
paintable = result->paintable;
else
return EventResult::Dropped;
@ -395,7 +403,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
document->set_hovered_node(node);
if (paintable->wants_mouse_events()) {
if (paintable->handle_mousedown({}, viewport_position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
if (paintable->handle_mousedown({}, position, button, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
return EventResult::Cancelled;
}
@ -404,7 +412,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
if (is<HTML::HTMLIFrameElement>(*node)) {
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
return content_navigable->event_handler().handle_mousedown(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
return content_navigable->event_handler().handle_mousedown(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
return EventResult::Dropped;
}
@ -418,9 +426,10 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
return EventResult::Dropped;
m_mousedown_target = node.ptr();
auto page_offset = compute_mouse_event_page_offset(viewport_position);
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousedown, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
auto offset = compute_mouse_event_offset(position, *layout_node);
auto client_offset = compute_mouse_event_client_offset(position);
auto page_offset = compute_mouse_event_page_offset(client_offset);
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousedown, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
}
// NOTE: Dispatching an event may have disturbed the world.
@ -428,7 +437,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
return EventResult::Accepted;
if (button == UIEvents::MouseButton::Primary) {
if (auto result = paint_root()->hit_test(viewport_position, Painting::HitTestType::TextCursor); result.has_value()) {
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::TextCursor); result.has_value()) {
auto paintable = result->paintable;
auto dom_node = paintable->dom_node();
if (dom_node) {
@ -485,6 +494,8 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
if (!m_navigable->active_document()->is_fully_active())
return EventResult::Dropped;
auto position = viewport_position;
m_navigable->active_document()->update_layout();
if (!paint_root())
@ -499,7 +510,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
GC::Ptr<Painting::Paintable> paintable;
Optional<int> start_index;
if (auto result = target_for_mouse_position(viewport_position); result.has_value()) {
if (auto result = target_for_mouse_position(position); result.has_value()) {
paintable = result->paintable;
start_index = result->index_in_node;
}
@ -508,7 +519,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
if (paintable) {
if (paintable->wants_mouse_events()) {
document.set_hovered_node(paintable->dom_node());
if (paintable->handle_mousemove({}, viewport_position, buttons, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
if (paintable->handle_mousemove({}, position, buttons, modifiers) == Painting::Paintable::DispatchEventOfSameName::No)
return EventResult::Cancelled;
// FIXME: It feels a bit aggressive to always update the cursor like this.
@ -519,7 +530,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
if (node && is<HTML::HTMLIFrameElement>(*node)) {
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
return content_navigable->event_handler().handle_mousemove(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, buttons, modifiers);
return content_navigable->event_handler().handle_mousemove(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, buttons, modifiers);
return EventResult::Dropped;
}
@ -552,13 +563,14 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
hovered_node_cursor = cursor_css_to_gfx(cursor);
}
auto page_offset = compute_mouse_event_page_offset(viewport_position);
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
auto offset = compute_mouse_event_offset(position, *layout_node);
auto client_offset = compute_mouse_event_client_offset(position);
auto page_offset = compute_mouse_event_page_offset(client_offset);
auto movement = compute_mouse_event_movement(screen_position);
m_mousemove_previous_screen_position = screen_position;
bool continue_ = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousemove, screen_position, page_offset, viewport_position, offset, movement, UIEvents::MouseButton::Primary, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
bool continue_ = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousemove, screen_position, page_offset, client_offset, offset, movement, UIEvents::MouseButton::Primary, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
if (!continue_)
return EventResult::Cancelled;
@ -568,7 +580,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
}
if (m_in_mouse_selection) {
auto hit = paint_root()->hit_test(viewport_position, Painting::HitTestType::TextCursor);
auto hit = paint_root()->hit_test(position, Painting::HitTestType::TextCursor);
if (m_mouse_selection_target) {
if (hit.has_value()) {
m_mouse_selection_target->set_selection_focus(*hit->paintable->dom_node(), hit->index_in_node);
@ -623,13 +635,16 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
auto& document = *m_navigable->active_document();
auto scroll_offset = document.navigable()->viewport_scroll_offset();
auto position = viewport_position.translated(scroll_offset);
document.update_layout();
if (!paint_root())
return EventResult::Dropped;
GC::Ptr<Painting::Paintable> paintable;
if (auto result = target_for_mouse_position(viewport_position); result.has_value())
if (auto result = target_for_mouse_position(position); result.has_value())
paintable = result->paintable;
else
return EventResult::Dropped;
@ -650,7 +665,7 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
if (is<HTML::HTMLIFrameElement>(*node)) {
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
return content_navigable->event_handler().handle_doubleclick(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
return content_navigable->event_handler().handle_doubleclick(position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
return EventResult::Dropped;
}
@ -660,16 +675,17 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
if (!parent_element_for_event_dispatch(*paintable, node, layout_node))
return EventResult::Dropped;
auto page_offset = compute_mouse_event_page_offset(viewport_position);
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::dblclick, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
auto offset = compute_mouse_event_offset(position, *layout_node);
auto client_offset = compute_mouse_event_client_offset(position);
auto page_offset = compute_mouse_event_page_offset(client_offset);
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::dblclick, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
// NOTE: Dispatching an event may have disturbed the world.
if (!paint_root() || paint_root() != node->document().paintable_box())
return EventResult::Accepted;
if (button == UIEvents::MouseButton::Primary) {
if (auto result = paint_root()->hit_test(viewport_position, Painting::HitTestType::TextCursor); result.has_value()) {
if (auto result = paint_root()->hit_test(position, Painting::HitTestType::TextCursor); result.has_value()) {
if (!result->paintable->dom_node())
return EventResult::Accepted;
if (!is<Painting::TextPaintable>(*result->paintable))
@ -722,18 +738,19 @@ EventResult EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPi
return EventResult::Dropped;
}
auto page_offset = compute_mouse_event_page_offset(viewport_position);
auto offset = compute_mouse_event_offset(page_offset, paintable->layout_node());
auto offset = compute_mouse_event_offset(viewport_position, paintable->layout_node());
auto client_offset = compute_mouse_event_client_offset(viewport_position);
auto page_offset = compute_mouse_event_page_offset(client_offset);
switch (type) {
case DragEvent::Type::DragStart:
return m_drag_and_drop_event_handler->handle_drag_start(document.realm(), screen_position, page_offset, viewport_position, offset, button, buttons, modifiers, move(files));
return m_drag_and_drop_event_handler->handle_drag_start(document.realm(), screen_position, page_offset, client_offset, offset, button, buttons, modifiers, move(files));
case DragEvent::Type::DragMove:
return m_drag_and_drop_event_handler->handle_drag_move(document.realm(), document, *node, screen_position, page_offset, viewport_position, offset, button, buttons, modifiers);
return m_drag_and_drop_event_handler->handle_drag_move(document.realm(), document, *node, screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
case DragEvent::Type::DragEnd:
return m_drag_and_drop_event_handler->handle_drag_leave(document.realm(), screen_position, page_offset, viewport_position, offset, button, buttons, modifiers);
return m_drag_and_drop_event_handler->handle_drag_leave(document.realm(), screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
case DragEvent::Type::Drop:
return m_drag_and_drop_event_handler->handle_drop(document.realm(), screen_position, page_offset, viewport_position, offset, button, buttons, modifiers);
return m_drag_and_drop_event_handler->handle_drop(document.realm(), screen_position, page_offset, client_offset, offset, button, buttons, modifiers);
}
VERIFY_NOT_REACHED();
@ -1096,6 +1113,15 @@ void EventHandler::set_mouse_event_tracking_paintable(Painting::Paintable* paint
m_mouse_event_tracking_paintable = paintable;
}
CSSPixelPoint EventHandler::compute_mouse_event_client_offset(CSSPixelPoint event_page_position) const
{
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-mouseevent-clientx
// The clientX attribute must return the x-coordinate of the position where the event occurred relative to the origin of the viewport.
auto scroll_offset = m_navigable->active_document()->navigable()->viewport_scroll_offset();
return event_page_position.translated(-scroll_offset);
}
CSSPixelPoint EventHandler::compute_mouse_event_page_offset(CSSPixelPoint event_client_offset) const
{
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-mouseevent-pagex

View file

@ -402,7 +402,6 @@ ErrorOr<void> generate_implementation_file(JsonObject& properties, Core::File& f
#include <LibWeb/CSS/Enums.h>
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/CSS/PropertyID.h>
#include <LibWeb/CSS/PropertyName.h>
#include <LibWeb/CSS/CSSStyleValue.h>
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
@ -437,9 +436,6 @@ Optional<PropertyID> property_id_from_camel_case_string(StringView string)
Optional<PropertyID> property_id_from_string(StringView string)
{
if (is_a_custom_property_name_string(string))
return PropertyID::Custom;
if (Infra::is_ascii_case_insensitive_match(string, "all"sv))
return PropertyID::All;
)~~~");

View file

@ -21,10 +21,3 @@ TEST_CASE(all_green)
EXPECT_EQ(Color(Color::NamedColor::Green), Color::from_xyz50(0.385152, 0.716887, 0.097081));
EXPECT_EQ(Color(Color::NamedColor::Green), Color::from_xyz65(0.357584, 0.715169, 0.119195));
}
TEST_CASE(hsv)
{
EXPECT_EQ(Color(51, 179, 51), Color::from_hsv(120, 0.714285714, .7));
EXPECT_EQ(Color(51, 179, 51, 128), Color::from_hsv(120, 0.714285714, .7).with_opacity(0.5));
EXPECT_EQ(Color(87, 128, 77), Color::from_hsv(108, 0.4, .5));
}

View file

@ -1,10 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Color 4: CSS Color 4: hwb</title>
<style>
.test { background-color: rgb(20% 70% 20%); width: 12em; height: 12em; } /* hwb(120 20% 30%) converted to sRGB */
</style>
<body>
<p>Test passes if you see a single square, and not two rectangles of different colors.</p>
<div class="test"></div>
</body>

View file

@ -1,17 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Color 4: hwb</title>
<link rel="author" title="Sam Weinig" href="mailto:weinig@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-color-4/#the-hwb-notation">
<link rel="match" href="../../../../expected/wpt-import/css/css-color/hwb-004-ref.html">
<meta name="assert" content="hwb with no alpha">
<style>
.test { background-color: red; width: 12em; height: 6em; margin-top: 0; }
.ref { background-color: rgb(20% 70% 20%); width: 12em; height: 6em; margin-bottom: 0; } /* hwb(120 20% 30%) converted to sRGB */
.test { background-color: hwb(120 20% 30%); }
</style>
<body>
<p>Test passes if you see a single square, and not two rectangles of different colors.</p>
<div class="ref"></div>
<div class="test"></div>
</body>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -1,10 +0,0 @@
x: 50
y: 50
screenX: 50
screenY: 50
clientX: 50
clientY: 50
pageX: 50
pageY: 60
offsetX: 42
offsetY: 52

View file

@ -1,4 +0,0 @@
style.getPropertyValue(--redcolor)=red
style.getPropertyPriority(--redcolor)=
rgb(255, 0, 0)
rgba(0, 0, 0, 0)

View file

@ -1,487 +0,0 @@
Summary
Harness status: OK
Rerun
Found 476 tests
410 Pass
66 Fail
Details
Result Test Name MessagePass Bad algorithm: generateKey(AES, false, [decrypt])
Pass Bad algorithm: generateKey(AES, true, [decrypt])
Pass Bad algorithm: generateKey(AES, RED, [decrypt])
Pass Bad algorithm: generateKey(AES, 7, [decrypt])
Pass Bad algorithm: generateKey(AES, false, [sign, decrypt])
Pass Bad algorithm: generateKey(AES, true, [sign, decrypt])
Pass Bad algorithm: generateKey(AES, RED, [sign, decrypt])
Pass Bad algorithm: generateKey(AES, 7, [sign, decrypt])
Pass Bad algorithm: generateKey(AES, false, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey(AES, true, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey(AES, RED, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey(AES, 7, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey(AES, false, [deriveBits, decrypt])
Pass Bad algorithm: generateKey(AES, true, [deriveBits, decrypt])
Pass Bad algorithm: generateKey(AES, RED, [deriveBits, decrypt])
Pass Bad algorithm: generateKey(AES, 7, [deriveBits, decrypt])
Pass Bad algorithm: generateKey(AES, false, [sign])
Pass Bad algorithm: generateKey(AES, true, [sign])
Pass Bad algorithm: generateKey(AES, RED, [sign])
Pass Bad algorithm: generateKey(AES, 7, [sign])
Pass Bad algorithm: generateKey(AES, false, [deriveBits, sign])
Pass Bad algorithm: generateKey(AES, true, [deriveBits, sign])
Pass Bad algorithm: generateKey(AES, RED, [deriveBits, sign])
Pass Bad algorithm: generateKey(AES, 7, [deriveBits, sign])
Pass Bad algorithm: generateKey(AES, false, [deriveBits])
Pass Bad algorithm: generateKey(AES, true, [deriveBits])
Pass Bad algorithm: generateKey(AES, RED, [deriveBits])
Pass Bad algorithm: generateKey(AES, 7, [deriveBits])
Pass Bad algorithm: generateKey(AES, false, [])
Pass Bad algorithm: generateKey(AES, true, [])
Pass Bad algorithm: generateKey(AES, RED, [])
Pass Bad algorithm: generateKey(AES, 7, [])
Pass Bad algorithm: generateKey(AES, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey(AES, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey(AES, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey(AES, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({name: AES}, false, [decrypt])
Pass Bad algorithm: generateKey({name: AES}, true, [decrypt])
Pass Bad algorithm: generateKey({name: AES}, RED, [decrypt])
Pass Bad algorithm: generateKey({name: AES}, 7, [decrypt])
Pass Bad algorithm: generateKey({name: AES}, false, [sign, decrypt])
Pass Bad algorithm: generateKey({name: AES}, true, [sign, decrypt])
Pass Bad algorithm: generateKey({name: AES}, RED, [sign, decrypt])
Pass Bad algorithm: generateKey({name: AES}, 7, [sign, decrypt])
Pass Bad algorithm: generateKey({name: AES}, false, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({name: AES}, true, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({name: AES}, RED, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({name: AES}, 7, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({name: AES}, false, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({name: AES}, true, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({name: AES}, RED, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({name: AES}, 7, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({name: AES}, false, [sign])
Pass Bad algorithm: generateKey({name: AES}, true, [sign])
Pass Bad algorithm: generateKey({name: AES}, RED, [sign])
Pass Bad algorithm: generateKey({name: AES}, 7, [sign])
Pass Bad algorithm: generateKey({name: AES}, false, [deriveBits, sign])
Pass Bad algorithm: generateKey({name: AES}, true, [deriveBits, sign])
Pass Bad algorithm: generateKey({name: AES}, RED, [deriveBits, sign])
Pass Bad algorithm: generateKey({name: AES}, 7, [deriveBits, sign])
Pass Bad algorithm: generateKey({name: AES}, false, [deriveBits])
Pass Bad algorithm: generateKey({name: AES}, true, [deriveBits])
Pass Bad algorithm: generateKey({name: AES}, RED, [deriveBits])
Pass Bad algorithm: generateKey({name: AES}, 7, [deriveBits])
Pass Bad algorithm: generateKey({name: AES}, false, [])
Pass Bad algorithm: generateKey({name: AES}, true, [])
Pass Bad algorithm: generateKey({name: AES}, RED, [])
Pass Bad algorithm: generateKey({name: AES}, 7, [])
Pass Bad algorithm: generateKey({name: AES}, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({name: AES}, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({name: AES}, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({name: AES}, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES}, false, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, true, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, RED, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, 7, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, false, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, true, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, RED, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, 7, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, false, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, true, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, RED, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, 7, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, false, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, true, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, RED, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, 7, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES}, false, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES}, true, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES}, RED, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES}, 7, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES}, false, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES}, true, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES}, RED, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES}, 7, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES}, false, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES}, true, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES}, RED, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES}, 7, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES}, false, [])
Pass Bad algorithm: generateKey({length: 128, name: AES}, true, [])
Pass Bad algorithm: generateKey({length: 128, name: AES}, RED, [])
Pass Bad algorithm: generateKey({length: 128, name: AES}, 7, [])
Pass Bad algorithm: generateKey({length: 128, name: AES}, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES}, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES}, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES}, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, false, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, true, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, RED, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, 7, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, false, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, true, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, RED, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, 7, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, false, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, true, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, RED, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, 7, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, false, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, true, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, RED, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, 7, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, false, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, true, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, RED, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, 7, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, false, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, true, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, RED, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, 7, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, false, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, true, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, RED, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, 7, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, false, [])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, true, [])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, RED, [])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, 7, [])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CMAC}, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, false, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, true, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, RED, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, 7, [decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, false, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, true, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, RED, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, 7, [sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, false, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, true, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, RED, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, 7, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, false, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, true, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, RED, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, 7, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, false, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, true, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, RED, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, 7, [sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, false, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, true, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, RED, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, 7, [deriveBits, sign])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, false, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, true, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, RED, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, 7, [deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, false, [])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, true, [])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, RED, [])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, 7, [])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({length: 128, name: AES-CFB}, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, false, [decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, true, [decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, RED, [decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, 7, [decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, false, [sign, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, true, [sign, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, RED, [sign, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, 7, [sign, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, false, [deriveBits, sign, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, true, [deriveBits, sign, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, RED, [deriveBits, sign, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, 7, [deriveBits, sign, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, false, [deriveBits, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, true, [deriveBits, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, RED, [deriveBits, decrypt])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, 7, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({hash: MD5, name: HMAC}, false, [sign])
Pass Bad algorithm: generateKey({hash: MD5, name: HMAC}, true, [sign])
Pass Bad algorithm: generateKey({hash: MD5, name: HMAC}, RED, [sign])
Pass Bad algorithm: generateKey({hash: MD5, name: HMAC}, 7, [sign])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, false, [deriveBits, sign])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, true, [deriveBits, sign])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, RED, [deriveBits, sign])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, 7, [deriveBits, sign])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, false, [deriveBits])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, true, [deriveBits])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, RED, [deriveBits])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, 7, [deriveBits])
Pass Bad algorithm: generateKey({hash: MD5, name: HMAC}, false, [])
Pass Bad algorithm: generateKey({hash: MD5, name: HMAC}, true, [])
Pass Bad algorithm: generateKey({hash: MD5, name: HMAC}, RED, [])
Pass Bad algorithm: generateKey({hash: MD5, name: HMAC}, 7, [])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Fail Bad algorithm: generateKey({hash: MD5, name: HMAC}, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [sign])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [sign])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [sign])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [sign])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [deriveBits, sign])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [deriveBits, sign])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [deriveBits, sign])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [deriveBits, sign])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [deriveBits])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [deriveBits])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [deriveBits])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [deriveBits])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({hash: SHA-256, modulusLength: 2048, name: RSA, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [sign])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [sign])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [sign])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [sign])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [deriveBits, sign])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [deriveBits, sign])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [deriveBits, sign])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [deriveBits, sign])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [deriveBits])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [deriveBits])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [deriveBits])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [deriveBits])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({hash: SHA, modulusLength: 2048, name: RSA-PSS, publicExponent: {0: 1, 1: 0, 2: 1}}, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, false, [decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, true, [decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, RED, [decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, 7, [decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, false, [sign, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, true, [sign, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, RED, [sign, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, 7, [sign, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, false, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, true, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, RED, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, 7, [deriveBits, sign, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, false, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, true, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, RED, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, 7, [deriveBits, decrypt])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, false, [sign])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, true, [sign])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, RED, [sign])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, 7, [sign])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, false, [deriveBits, sign])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, true, [deriveBits, sign])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, RED, [deriveBits, sign])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, 7, [deriveBits, sign])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, false, [deriveBits])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, true, [deriveBits])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, RED, [deriveBits])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, 7, [deriveBits])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, false, [])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, true, [])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, RED, [])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, 7, [])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad algorithm: generateKey({name: EC, namedCurve: P521}, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Fail Empty algorithm: generateKey({}, false, [decrypt])
Fail Empty algorithm: generateKey({}, true, [decrypt])
Fail Empty algorithm: generateKey({}, RED, [decrypt])
Fail Empty algorithm: generateKey({}, 7, [decrypt])
Fail Empty algorithm: generateKey({}, false, [sign, decrypt])
Fail Empty algorithm: generateKey({}, true, [sign, decrypt])
Fail Empty algorithm: generateKey({}, RED, [sign, decrypt])
Fail Empty algorithm: generateKey({}, 7, [sign, decrypt])
Fail Empty algorithm: generateKey({}, false, [deriveBits, sign, decrypt])
Fail Empty algorithm: generateKey({}, true, [deriveBits, sign, decrypt])
Fail Empty algorithm: generateKey({}, RED, [deriveBits, sign, decrypt])
Fail Empty algorithm: generateKey({}, 7, [deriveBits, sign, decrypt])
Fail Empty algorithm: generateKey({}, false, [deriveBits, decrypt])
Fail Empty algorithm: generateKey({}, true, [deriveBits, decrypt])
Fail Empty algorithm: generateKey({}, RED, [deriveBits, decrypt])
Fail Empty algorithm: generateKey({}, 7, [deriveBits, decrypt])
Fail Empty algorithm: generateKey({}, false, [sign])
Fail Empty algorithm: generateKey({}, true, [sign])
Fail Empty algorithm: generateKey({}, RED, [sign])
Fail Empty algorithm: generateKey({}, 7, [sign])
Fail Empty algorithm: generateKey({}, false, [deriveBits, sign])
Fail Empty algorithm: generateKey({}, true, [deriveBits, sign])
Fail Empty algorithm: generateKey({}, RED, [deriveBits, sign])
Fail Empty algorithm: generateKey({}, 7, [deriveBits, sign])
Fail Empty algorithm: generateKey({}, false, [deriveBits])
Fail Empty algorithm: generateKey({}, true, [deriveBits])
Fail Empty algorithm: generateKey({}, RED, [deriveBits])
Fail Empty algorithm: generateKey({}, 7, [deriveBits])
Fail Empty algorithm: generateKey({}, false, [])
Fail Empty algorithm: generateKey({}, true, [])
Fail Empty algorithm: generateKey({}, RED, [])
Fail Empty algorithm: generateKey({}, 7, [])
Fail Empty algorithm: generateKey({}, false, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Fail Empty algorithm: generateKey({}, true, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Fail Empty algorithm: generateKey({}, RED, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Fail Empty algorithm: generateKey({}, 7, [decrypt, sign, deriveBits, decrypt, sign, deriveBits])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, encrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, decrypt])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, sign])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, verify])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, wrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, unwrapKey])
Pass Bad usages: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits, unwrapKey])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, false, [deriveKey])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, true, [deriveKey])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, false, [deriveBits, deriveKey])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, true, [deriveBits, deriveKey])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, false, [deriveBits])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, true, [deriveBits])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, false, [])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, true, [])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: P-512}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, false, [deriveKey])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, true, [deriveKey])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, false, [deriveBits, deriveKey])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, true, [deriveBits, deriveKey])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, false, [deriveBits])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, true, [deriveBits])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, false, [])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, true, [])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Pass Bad algorithm property: generateKey({name: ECDH, namedCurve: Curve25519}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Pass Empty usages: generateKey({name: ECDH, namedCurve: P-256}, false, [])
Pass Empty usages: generateKey({name: ECDH, namedCurve: P-256}, true, [])
Pass Empty usages: generateKey({name: ECDH, namedCurve: P-384}, false, [])
Pass Empty usages: generateKey({name: ECDH, namedCurve: P-384}, true, [])
Fail Empty usages: generateKey({name: ECDH, namedCurve: P-521}, false, [])
Fail Empty usages: generateKey({name: ECDH, namedCurve: P-521}, true, [])

View file

@ -1,82 +0,0 @@
Summary
Harness status: OK
Rerun
Found 72 tests
72 Fail
Details
Result Test Name MessageFail Success: generateKey({name: ECDH, namedCurve: P-256}, false, [deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-256}, false, [deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-256}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-384}, false, [deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-384}, false, [deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-384}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-521}, false, [deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey])
Fail Success: generateKey({name: ECDH, namedCurve: P-521}, false, [deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-521}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-256}, false, [deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-256}, true, [deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-256}, false, [deriveBits, deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-256}, true, [deriveBits, deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-256}, false, [deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-256}, true, [deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-256}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-384}, false, [deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-384}, true, [deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-384}, false, [deriveBits, deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-384}, true, [deriveBits, deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-384}, false, [deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-384}, true, [deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-384}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-521}, false, [deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-521}, true, [deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-521}, false, [deriveBits, deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-521}, true, [deriveBits, deriveKey])
Fail Success: generateKey({name: ecdh, namedCurve: P-521}, false, [deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-521}, true, [deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-521}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: ecdh, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-256}, false, [deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-256}, true, [deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-256}, false, [deriveBits, deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-256}, true, [deriveBits, deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-256}, false, [deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-256}, true, [deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-256}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-384}, false, [deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-384}, true, [deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-384}, false, [deriveBits, deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-384}, true, [deriveBits, deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-384}, false, [deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-384}, true, [deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-384}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-521}, false, [deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-521}, true, [deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-521}, false, [deriveBits, deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-521}, true, [deriveBits, deriveKey])
Fail Success: generateKey({name: Ecdh, namedCurve: P-521}, false, [deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-521}, true, [deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-521}, false, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])
Fail Success: generateKey({name: Ecdh, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits, deriveKey, deriveBits])

View file

@ -1,32 +0,0 @@
<!DOCTYPE html>
<style>
div {
width: 100px;
height: 100px;
background-color: gray;
}
body {
height: 200vh;
}
</style>
<div onClick="
println(`x: ${event.x}`);
println(`y: ${event.y}`);
println(`screenX: ${event.screenX}`);
println(`screenY: ${event.screenY}`);
println(`clientX: ${event.clientX}`);
println(`clientY: ${event.clientY}`);
println(`pageX: ${event.pageX}`);
println(`pageY: ${event.pageY}`);
println(`offsetX: ${event.offsetX}`);
println(`offsetY: ${event.offsetY}`);
"></div>
<script src="../include.js"></script>
<script>
test(() => {
window.scrollBy(0, 10)
internals.click(50, 50);
});
</script>

View file

@ -1,24 +0,0 @@
<!DOCTYPE html>
<script src="../include.js"></script>
<body></body>
<script>
test(() => {
const div = document.createElement('div');
div.style.setProperty("--redcolor", "red");
println(`style.getPropertyValue(--redcolor)=${div.style.getPropertyValue("--redcolor")}`);
println(`style.getPropertyPriority(--redcolor)=${div.style.getPropertyPriority("--redcolor")}`);
const nested = document.createElement('div');
nested.style["backgroundColor"] = "var(--redcolor)";
nested.style["width"] = "100px";
nested.style["height"] = "100px";
div.appendChild(nested);
document.body.appendChild(div);
println(getComputedStyle(nested).backgroundColor);
div.style.removeProperty("--redcolor");
println(getComputedStyle(nested).backgroundColor);
});
</script>

View file

@ -1,228 +0,0 @@
function run_test(algorithmNames) {
var subtle = crypto.subtle; // Change to test prefixed implementations
setup({explicit_timeout: true});
// These tests check that generateKey throws an error, and that
// the error is of the right type, for a wide set of incorrect parameters.
//
// Error testing occurs by setting the parameter that should trigger the
// error to an invalid value, then combining that with all valid
// parameters that should be checked earlier by generateKey, and all
// valid and invalid parameters that should be checked later by
// generateKey.
//
// There are a lot of combinations of possible parameters for both
// success and failure modes, resulting in a very large number of tests
// performed.
// Setup: define the correct behaviors that should be sought, and create
// helper functions that generate all possible test parameters for
// different situations.
var allTestVectors = [ // Parameters that should work for generateKey
{name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []},
{name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []},
{name: "AES-GCM", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []},
{name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []},
{name: "HMAC", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []},
{name: "RSASSA-PKCS1-v1_5", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "RSA-PSS", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "RSA-OAEP", resultType: "CryptoKeyPair", usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: ["decrypt", "unwrapKey"]},
{name: "ECDSA", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "ECDH", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]},
{name: "Ed25519", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "Ed448", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "X25519", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]},
{name: "X448", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]},
];
var testVectors = [];
if (algorithmNames && !Array.isArray(algorithmNames)) {
algorithmNames = [algorithmNames];
};
allTestVectors.forEach(function(vector) {
if (!algorithmNames || algorithmNames.includes(vector.name)) {
testVectors.push(vector);
}
});
function parameterString(algorithm, extractable, usages) {
if (typeof algorithm !== "object" && typeof algorithm !== "string") {
alert(algorithm);
}
var result = "(" +
objectToString(algorithm) + ", " +
objectToString(extractable) + ", " +
objectToString(usages) +
")";
return result;
}
// Test that a given combination of parameters results in an error,
// AND that it is the correct kind of error.
//
// Expected error is either a number, tested against the error code,
// or a string, tested against the error name.
function testError(algorithm, extractable, usages, expectedError, testTag) {
promise_test(function(test) {
return crypto.subtle.generateKey(algorithm, extractable, usages)
.then(function(result) {
assert_unreached("Operation succeeded, but should not have");
}, function(err) {
if (typeof expectedError === "number") {
assert_equals(err.code, expectedError, testTag + " not supported");
} else {
assert_equals(err.name, expectedError, testTag + " not supported");
}
});
}, testTag + ": generateKey" + parameterString(algorithm, extractable, usages));
}
// Given an algorithm name, create several invalid parameters.
function badAlgorithmPropertySpecifiersFor(algorithmName) {
var results = [];
if (algorithmName.toUpperCase().substring(0, 3) === "AES") {
// Specifier properties are name and length
[64, 127, 129, 255, 257, 512].forEach(function(length) {
results.push({name: algorithmName, length: length});
});
} else if (algorithmName.toUpperCase().substring(0, 3) === "RSA") {
[new Uint8Array([1]), new Uint8Array([1,0,0])].forEach(function(publicExponent) {
results.push({name: algorithmName, hash: "SHA-256", modulusLength: 1024, publicExponent: publicExponent});
});
} else if (algorithmName.toUpperCase().substring(0, 2) === "EC") {
["P-512", "Curve25519"].forEach(function(curveName) {
results.push({name: algorithmName, namedCurve: curveName});
});
}
return results;
}
// Don't create an exhaustive list of all invalid usages,
// because there would usually be nearly 2**8 of them,
// way too many to test. Instead, create every singleton
// of an illegal usage, and "poison" every valid usage
// with an illegal one.
function invalidUsages(validUsages, mandatoryUsages) {
var results = [];
var illegalUsages = [];
["encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey", "deriveKey", "deriveBits"].forEach(function(usage) {
if (!validUsages.includes(usage)) {
illegalUsages.push(usage);
}
});
var goodUsageCombinations = allValidUsages(validUsages, false, mandatoryUsages);
illegalUsages.forEach(function(illegalUsage) {
results.push([illegalUsage]);
goodUsageCombinations.forEach(function(usageCombination) {
results.push(usageCombination.concat([illegalUsage]));
});
});
return results;
}
// Now test for properly handling errors
// - Unsupported algorithm
// - Bad usages for algorithm
// - Bad key lengths
// Algorithm normalization should fail with "Not supported"
var badAlgorithmNames = [
"AES",
{name: "AES"},
{name: "AES", length: 128},
{name: "AES-CMAC", length: 128}, // Removed after CR
{name: "AES-CFB", length: 128}, // Removed after CR
{name: "HMAC", hash: "MD5"},
{name: "RSA", hash: "SHA-256", modulusLength: 2048, publicExponent: new Uint8Array([1,0,1])},
{name: "RSA-PSS", hash: "SHA", modulusLength: 2048, publicExponent: new Uint8Array([1,0,1])},
{name: "EC", namedCurve: "P521"}
];
// Algorithm normalization failures should be found first
// - all other parameters can be good or bad, should fail
// due to NotSupportedError.
badAlgorithmNames.forEach(function(algorithm) {
allValidUsages(["decrypt", "sign", "deriveBits"], true, []) // Small search space, shouldn't matter because should fail before used
.forEach(function(usages) {
[false, true, "RED", 7].forEach(function(extractable){
testError(algorithm, extractable, usages, "NotSupportedError", "Bad algorithm");
});
});
});
// Empty algorithm should fail with TypeError
allValidUsages(["decrypt", "sign", "deriveBits"], true, []) // Small search space, shouldn't matter because should fail before used
.forEach(function(usages) {
[false, true, "RED", 7].forEach(function(extractable){
testError({}, extractable, usages, "TypeError", "Empty algorithm");
});
});
// Algorithms normalize okay, but usages bad (though not empty).
// It shouldn't matter what other extractable is. Should fail
// due to SyntaxError
testVectors.forEach(function(vector) {
var name = vector.name;
allAlgorithmSpecifiersFor(name).forEach(function(algorithm) {
invalidUsages(vector.usages, vector.mandatoryUsages).forEach(function(usages) {
[true].forEach(function(extractable) {
testError(algorithm, extractable, usages, "SyntaxError", "Bad usages");
});
});
});
});
// Other algorithm properties should be checked next, so try good
// algorithm names and usages, but bad algorithm properties next.
// - Special case: normally bad usage [] isn't checked until after properties,
// so it's included in this test case. It should NOT cause an error.
testVectors.forEach(function(vector) {
var name = vector.name;
badAlgorithmPropertySpecifiersFor(name).forEach(function(algorithm) {
allValidUsages(vector.usages, true, vector.mandatoryUsages)
.forEach(function(usages) {
[false, true].forEach(function(extractable) {
if (name.substring(0,2) === "EC") {
testError(algorithm, extractable, usages, "NotSupportedError", "Bad algorithm property");
} else {
testError(algorithm, extractable, usages, "OperationError", "Bad algorithm property");
}
});
});
});
});
// The last thing that should be checked is empty usages (disallowed for secret and private keys).
testVectors.forEach(function(vector) {
var name = vector.name;
allAlgorithmSpecifiersFor(name).forEach(function(algorithm) {
var usages = [];
[false, true].forEach(function(extractable) {
testError(algorithm, extractable, usages, "SyntaxError", "Empty usages");
});
});
});
}

View file

@ -1,17 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>WebCryptoAPI: generateKey() for Failures</title>
<meta name="timeout" content="long">
<script>
self.GLOBAL = {
isWindow: function() { return true; },
isWorker: function() { return false; },
isShadowRealm: function() { return false; },
};
</script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../util/helpers.js"></script>
<script src="failures.js"></script>
<div id=log></div>
<script src="../../WebCryptoAPI/generateKey/failures_ECDH.https.any.js"></script>

View file

@ -1,5 +0,0 @@
// META: title=WebCryptoAPI: generateKey() for Failures
// META: timeout=long
// META: script=../util/helpers.js
// META: script=failures.js
run_test(["ECDH"]);

View file

@ -1,115 +0,0 @@
function run_test(algorithmNames, slowTest) {
var subtle = crypto.subtle; // Change to test prefixed implementations
setup({explicit_timeout: true});
// These tests check that generateKey successfully creates keys
// when provided any of a wide set of correct parameters
// and that they can be exported afterwards.
//
// There are a lot of combinations of possible parameters,
// resulting in a very large number of tests
// performed.
// Setup: define the correct behaviors that should be sought, and create
// helper functions that generate all possible test parameters for
// different situations.
var allTestVectors = [ // Parameters that should work for generateKey
{name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []},
{name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []},
{name: "AES-GCM", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []},
{name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []},
{name: "HMAC", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []},
{name: "RSASSA-PKCS1-v1_5", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "RSA-PSS", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "RSA-OAEP", resultType: "CryptoKeyPair", usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: ["decrypt", "unwrapKey"]},
{name: "ECDSA", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "ECDH", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]},
{name: "Ed25519", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "Ed448", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
{name: "X25519", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]},
{name: "X448", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]},
];
var testVectors = [];
if (algorithmNames && !Array.isArray(algorithmNames)) {
algorithmNames = [algorithmNames];
};
allTestVectors.forEach(function(vector) {
if (!algorithmNames || algorithmNames.includes(vector.name)) {
testVectors.push(vector);
}
});
function parameterString(algorithm, extractable, usages) {
var result = "(" +
objectToString(algorithm) + ", " +
objectToString(extractable) + ", " +
objectToString(usages) +
")";
return result;
}
// Test that a given combination of parameters is successful
function testSuccess(algorithm, extractable, usages, resultType, testTag) {
// algorithm, extractable, and usages are the generateKey parameters
// resultType is the expected result, either the CryptoKey object or "CryptoKeyPair"
// testTag is a string to prepend to the test name.
promise_test(function(test) {
return subtle.generateKey(algorithm, extractable, usages)
.then(function(result) {
if (resultType === "CryptoKeyPair") {
assert_goodCryptoKey(result.privateKey, algorithm, extractable, usages, "private");
assert_goodCryptoKey(result.publicKey, algorithm, true, usages, "public");
} else {
assert_goodCryptoKey(result, algorithm, extractable, usages, "secret");
}
return result;
}, function(err) {
assert_unreached("generateKey threw an unexpected error: " + err.toString());
})
.then(async function (result) {
if (resultType === "CryptoKeyPair") {
await Promise.all([
subtle.exportKey('jwk', result.publicKey),
subtle.exportKey('spki', result.publicKey),
result.publicKey.algorithm.name.startsWith('RSA') ? undefined : subtle.exportKey('raw', result.publicKey),
...(extractable ? [
subtle.exportKey('jwk', result.privateKey),
subtle.exportKey('pkcs8', result.privateKey),
] : [])
]);
} else {
if (extractable) {
await Promise.all([
subtle.exportKey('raw', result),
subtle.exportKey('jwk', result),
]);
}
}
}, function(err) {
assert_unreached("exportKey threw an unexpected error: " + err.toString());
})
}, testTag + ": generateKey" + parameterString(algorithm, extractable, usages));
}
// Test all valid sets of parameters for successful
// key generation.
testVectors.forEach(function(vector) {
allNameVariants(vector.name, slowTest).forEach(function(name) {
allAlgorithmSpecifiersFor(name).forEach(function(algorithm) {
allValidUsages(vector.usages, false, vector.mandatoryUsages).forEach(function(usages) {
[false, true].forEach(function(extractable) {
subsetTest(testSuccess, algorithm, extractable, usages, vector.resultType, "Success");
});
});
});
});
});
}

View file

@ -1,18 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>WebCryptoAPI: generateKey() Successful Calls</title>
<meta name="timeout" content="long">
<script>
self.GLOBAL = {
isWindow: function() { return true; },
isWorker: function() { return false; },
isShadowRealm: function() { return false; },
};
</script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../util/helpers.js"></script>
<script src="../../common/subset-tests.js"></script>
<script src="successes.js"></script>
<div id=log></div>
<script src="../../WebCryptoAPI/generateKey/successes_ECDH.https.any.js"></script>

View file

@ -1,6 +0,0 @@
// META: title=WebCryptoAPI: generateKey() Successful Calls
// META: timeout=long
// META: script=../util/helpers.js
// META: script=/common/subset-tests.js
// META: script=successes.js
run_test(["ECDH"]);

View file

@ -1,299 +0,0 @@
//
// helpers.js
//
// Helper functions used by several WebCryptoAPI tests
//
var registeredAlgorithmNames = [
"RSASSA-PKCS1-v1_5",
"RSA-PSS",
"RSA-OAEP",
"ECDSA",
"ECDH",
"AES-CTR",
"AES-CBC",
"AES-GCM",
"AES-KW",
"HMAC",
"SHA-1",
"SHA-256",
"SHA-384",
"SHA-512",
"HKDF",
"PBKDF2",
"Ed25519",
"Ed448",
"X25519",
"X448"
];
// Treats an array as a set, and generates an array of all non-empty
// subsets (which are themselves arrays).
//
// The order of members of the "subsets" is not guaranteed.
function allNonemptySubsetsOf(arr) {
var results = [];
var firstElement;
var remainingElements;
for(var i=0; i<arr.length; i++) {
firstElement = arr[i];
remainingElements = arr.slice(i+1);
results.push([firstElement]);
if (remainingElements.length > 0) {
allNonemptySubsetsOf(remainingElements).forEach(function(combination) {
combination.push(firstElement);
results.push(combination);
});
}
}
return results;
}
// Create a string representation of keyGeneration parameters for
// test names and labels.
function objectToString(obj) {
var keyValuePairs = [];
if (Array.isArray(obj)) {
return "[" + obj.map(function(elem){return objectToString(elem);}).join(", ") + "]";
} else if (typeof obj === "object") {
Object.keys(obj).sort().forEach(function(keyName) {
keyValuePairs.push(keyName + ": " + objectToString(obj[keyName]));
});
return "{" + keyValuePairs.join(", ") + "}";
} else if (typeof obj === "undefined") {
return "undefined";
} else {
return obj.toString();
}
var keyValuePairs = [];
Object.keys(obj).sort().forEach(function(keyName) {
var value = obj[keyName];
if (typeof value === "object") {
value = objectToString(value);
} else if (typeof value === "array") {
value = "[" + value.map(function(elem){return objectToString(elem);}).join(", ") + "]";
} else {
value = value.toString();
}
keyValuePairs.push(keyName + ": " + value);
});
return "{" + keyValuePairs.join(", ") + "}";
}
// Is key a CryptoKey object with correct algorithm, extractable, and usages?
// Is it a secret, private, or public kind of key?
function assert_goodCryptoKey(key, algorithm, extractable, usages, kind) {
var correctUsages = [];
var registeredAlgorithmName;
registeredAlgorithmNames.forEach(function(name) {
if (name.toUpperCase() === algorithm.name.toUpperCase()) {
registeredAlgorithmName = name;
}
});
assert_equals(key.constructor, CryptoKey, "Is a CryptoKey");
assert_equals(key.type, kind, "Is a " + kind + " key");
assert_equals(key.extractable, extractable, "Extractability is correct");
assert_equals(key.algorithm.name, registeredAlgorithmName, "Correct algorithm name");
if (key.algorithm.name.toUpperCase() === "HMAC" && algorithm.length === undefined) {
switch (key.algorithm.hash.name.toUpperCase()) {
case 'SHA-1':
case 'SHA-256':
assert_equals(key.algorithm.length, 512, "Correct length");
break;
case 'SHA-384':
case 'SHA-512':
assert_equals(key.algorithm.length, 1024, "Correct length");
break;
default:
assert_unreached("Unrecognized hash");
}
} else {
assert_equals(key.algorithm.length, algorithm.length, "Correct length");
}
if (["HMAC", "RSASSA-PKCS1-v1_5", "RSA-PSS"].includes(registeredAlgorithmName)) {
assert_equals(key.algorithm.hash.name.toUpperCase(), algorithm.hash.toUpperCase(), "Correct hash function");
}
if (/^(?:Ed|X)(?:25519|448)$/.test(key.algorithm.name)) {
assert_false('namedCurve' in key.algorithm, "Does not have a namedCurve property");
}
// usages is expected to be provided for a key pair, but we are checking
// only a single key. The publicKey and privateKey portions of a key pair
// recognize only some of the usages appropriate for a key pair.
if (key.type === "public") {
["encrypt", "verify", "wrapKey"].forEach(function(usage) {
if (usages.includes(usage)) {
correctUsages.push(usage);
}
});
} else if (key.type === "private") {
["decrypt", "sign", "unwrapKey", "deriveKey", "deriveBits"].forEach(function(usage) {
if (usages.includes(usage)) {
correctUsages.push(usage);
}
});
} else {
correctUsages = usages;
}
assert_equals((typeof key.usages), "object", key.type + " key.usages is an object");
assert_not_equals(key.usages, null, key.type + " key.usages isn't null");
// The usages parameter could have repeats, but the usages
// property of the result should not.
var usageCount = 0;
key.usages.forEach(function(usage) {
usageCount += 1;
assert_in_array(usage, correctUsages, "Has " + usage + " usage");
});
assert_equals(key.usages.length, usageCount, "usages property is correct");
assert_equals(key[Symbol.toStringTag], 'CryptoKey', "has the expected Symbol.toStringTag");
}
// The algorithm parameter is an object with a name and other
// properties. Given the name, generate all valid parameters.
function allAlgorithmSpecifiersFor(algorithmName) {
var results = [];
// RSA key generation is slow. Test a minimal set of parameters
var hashes = ["SHA-1", "SHA-256"];
// EC key generation is a lot faster. Check all curves in the spec
var curves = ["P-256", "P-384", "P-521"];
if (algorithmName.toUpperCase().substring(0, 3) === "AES") {
// Specifier properties are name and length
[128, 192, 256].forEach(function(length) {
results.push({name: algorithmName, length: length});
});
} else if (algorithmName.toUpperCase() === "HMAC") {
[
{hash: "SHA-1", length: 160},
{hash: "SHA-256", length: 256},
{hash: "SHA-384", length: 384},
{hash: "SHA-512", length: 512},
{hash: "SHA-1"},
{hash: "SHA-256"},
{hash: "SHA-384"},
{hash: "SHA-512"},
].forEach(function(hashAlgorithm) {
results.push({name: algorithmName, ...hashAlgorithm});
});
} else if (algorithmName.toUpperCase().substring(0, 3) === "RSA") {
hashes.forEach(function(hashName) {
results.push({name: algorithmName, hash: hashName, modulusLength: 2048, publicExponent: new Uint8Array([1,0,1])});
});
} else if (algorithmName.toUpperCase().substring(0, 2) === "EC") {
curves.forEach(function(curveName) {
results.push({name: algorithmName, namedCurve: curveName});
});
} else if (algorithmName.toUpperCase().substring(0, 1) === "X" || algorithmName.toUpperCase().substring(0, 2) === "ED") {
results.push({ name: algorithmName });
}
return results;
}
// Create every possible valid usages parameter, given legal
// usages. Note that an empty usages parameter is not always valid.
//
// There is an optional parameter - mandatoryUsages. If provided,
// it should be an array containing those usages of which one must be
// included.
function allValidUsages(validUsages, emptyIsValid, mandatoryUsages) {
if (typeof mandatoryUsages === "undefined") {
mandatoryUsages = [];
}
var okaySubsets = [];
allNonemptySubsetsOf(validUsages).forEach(function(subset) {
if (mandatoryUsages.length === 0) {
okaySubsets.push(subset);
} else {
for (var i=0; i<mandatoryUsages.length; i++) {
if (subset.includes(mandatoryUsages[i])) {
okaySubsets.push(subset);
return;
}
}
}
});
if (emptyIsValid && validUsages.length !== 0) {
okaySubsets.push([]);
}
okaySubsets.push(validUsages.concat(mandatoryUsages).concat(validUsages)); // Repeated values are allowed
return okaySubsets;
}
function unique(names) {
return [...new Set(names)];
}
// Algorithm name specifiers are case-insensitive. Generate several
// case variations of a given name.
function allNameVariants(name, slowTest) {
var upCaseName = name.toUpperCase();
var lowCaseName = name.toLowerCase();
var mixedCaseName = upCaseName.substring(0, 1) + lowCaseName.substring(1);
// for slow tests effectively cut the amount of work in third by only
// returning one variation
if (slowTest) return [mixedCaseName];
return unique([upCaseName, lowCaseName, mixedCaseName]);
}
// Builds a hex string representation for an array-like input.
// "bytes" can be an Array of bytes, an ArrayBuffer, or any TypedArray.
// The output looks like this:
// ab034c99
function bytesToHexString(bytes)
{
if (!bytes)
return null;
bytes = new Uint8Array(bytes);
var hexBytes = [];
for (var i = 0; i < bytes.length; ++i) {
var byteString = bytes[i].toString(16);
if (byteString.length < 2)
byteString = "0" + byteString;
hexBytes.push(byteString);
}
return hexBytes.join("");
}
function hexStringToUint8Array(hexString)
{
if (hexString.length % 2 != 0)
throw "Invalid hexString";
var arrayBuffer = new Uint8Array(hexString.length / 2);
for (var i = 0; i < hexString.length; i += 2) {
var byteValue = parseInt(hexString.substr(i, 2), 16);
if (byteValue == NaN)
throw "Invalid hexString";
arrayBuffer[i/2] = byteValue;
}
return arrayBuffer;
}

View file

@ -1,60 +0,0 @@
(function() {
var subTestStart = 0;
var subTestEnd = Infinity;
var match;
if (location.search) {
match = /(?:^\?|&)(\d+)-(\d+|last)(?:&|$)/.exec(location.search);
if (match) {
subTestStart = parseInt(match[1], 10);
if (match[2] !== "last") {
subTestEnd = parseInt(match[2], 10);
}
}
// Below is utility code to generate <meta> for copy/paste into tests.
// Sample usage:
// test.html?split=1000
match = /(?:^\?|&)split=(\d+)(?:&|$)/.exec(location.search);
if (match) {
var testsPerVariant = parseInt(match[1], 10);
add_completion_callback(tests => {
var total = tests.length;
var template = '<meta name="variant" content="?%s-%s">';
var metas = [];
for (var i = 1; i < total - testsPerVariant; i = i + testsPerVariant) {
metas.push(template.replace("%s", i).replace("%s", i + testsPerVariant - 1));
}
metas.push(template.replace("%s", i).replace("%s", "last"));
var pre = document.createElement('pre');
pre.textContent = metas.join('\n');
document.body.insertBefore(pre, document.body.firstChild);
document.getSelection().selectAllChildren(pre);
});
}
}
/**
* Check if `currentSubTest` is in the subset specified in the URL.
* @param {number} currentSubTest
* @returns {boolean}
*/
function shouldRunSubTest(currentSubTest) {
return currentSubTest >= subTestStart && currentSubTest <= subTestEnd;
}
var currentSubTest = 0;
/**
* Only test a subset of tests with, e.g., `?1-10` in the URL.
* Can be used together with `<meta name="variant" content="...">`
* Sample usage:
* for (const test of tests) {
* subsetTest(async_test, test.fn, test.name);
* }
*/
function subsetTest(testFunc, ...args) {
currentSubTest++;
if (shouldRunSubTest(currentSubTest)) {
return testFunc(...args);
}
return null;
}
self.shouldRunSubTest = shouldRunSubTest;
self.subsetTest = subsetTest;
})();