浏览代码

LibCrypto+LibWeb: Reorganize OID ASN1 constants

I have divided ANS1 constants by length so that they don't have
trailing zeros that need to be removed.

Also moved OIDs lists to the only place they are used for clarity.

Fixed a couple of WPT tests by adding SECP521r1 to the list of known
curves.
devgianlu 7 月之前
父节点
当前提交
ab2960e49f

+ 31 - 18
Libraries/LibCrypto/Certificate/Certificate.cpp

@@ -109,15 +109,17 @@ ErrorOr<Vector<int>> parse_ec_parameters(Crypto::ASN1::Decoder& decoder, Vector<
     // }
     PUSH_SCOPE("ECParameters"sv);
     READ_OBJECT(ObjectIdentifier, Vector<int>, named_curve);
-    // Note: namedCurve sometimes has 5 nodes, but we need 7 for the comparison below to work.
-    while (named_curve.size() < 7) {
-        named_curve.append(0);
-    }
     POP_SCOPE();
 
+    constexpr static Array<Span<int const>, 3> known_curve_identifiers {
+        secp256r1_oid,
+        secp384r1_oid,
+        secp521r1_oid
+    };
+
     bool is_known_curve = false;
     for (auto const& curves : known_curve_identifiers) {
-        if (curves.span() == named_curve.span()) {
+        if (curves == named_curve.span()) {
             is_known_curve = true;
             break;
         }
@@ -139,15 +141,26 @@ static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(Crypto::ASN1::Dec
     ENTER_TYPED_SCOPE(Sequence, "AlgorithmIdentifier"sv);
     PUSH_SCOPE("algorithm"sv);
     READ_OBJECT(ObjectIdentifier, Vector<int>, algorithm);
-    // Note: ecPublicKey only has 6 nodes, but we need 7 for the comparison below to work.
-    while (algorithm.size() < 7) {
-        algorithm.append(0);
-    }
     POP_SCOPE();
 
+    constexpr static Array<Span<int const>, 12> known_algorithm_identifiers {
+        rsa_encryption_oid,
+        rsa_md5_encryption_oid,
+        rsa_sha1_encryption_oid,
+        rsa_sha256_encryption_oid,
+        rsa_sha384_encryption_oid,
+        rsa_sha512_encryption_oid,
+        ecdsa_with_sha256_encryption_oid,
+        ecdsa_with_sha384_encryption_oid,
+        ec_public_key_encryption_oid,
+        x25519_oid,
+        ed25519_oid,
+        x448_oid,
+    };
+
     bool is_known_algorithm = false;
     for (auto const& inner : known_algorithm_identifiers) {
-        if (inner.span() == algorithm.span()) {
+        if (inner == algorithm.span()) {
             is_known_algorithm = true;
             break;
         }
@@ -166,7 +179,7 @@ static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(Crypto::ASN1::Dec
     //      sha384WithRSAEncryption  OBJECT IDENTIFIER  ::=  { pkcs-1 12 }
     //      sha512WithRSAEncryption  OBJECT IDENTIFIER  ::=  { pkcs-1 13 }
     //      sha224WithRSAEncryption  OBJECT IDENTIFIER  ::=  { pkcs-1 14 }
-    Array<Array<int, 7>, 8> rsa_null_algorithms = {
+    constexpr static Array<Span<int const>, 8> rsa_null_algorithms = {
         rsa_encryption_oid,
         rsa_md5_encryption_oid,
         rsa_sha1_encryption_oid,
@@ -178,7 +191,7 @@ static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(Crypto::ASN1::Dec
 
     bool is_rsa_null_algorithm = false;
     for (auto const& inner : rsa_null_algorithms) {
-        if (inner.span() == algorithm.span()) {
+        if (inner == algorithm.span()) {
             is_rsa_null_algorithm = true;
             break;
         }
@@ -202,7 +215,7 @@ static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(Crypto::ASN1::Dec
 
     // https://datatracker.ietf.org/doc/html/rfc8410#section-9
     // For all of the OIDs, the parameters MUST be absent.
-    Array<Array<int, 7>, 8> no_parameter_algorithms = {
+    constexpr static Array<Span<int const>, 8> no_parameter_algorithms = {
         ecdsa_with_sha224_encryption_oid,
         ecdsa_with_sha256_encryption_oid,
         ecdsa_with_sha384_encryption_oid,
@@ -215,7 +228,7 @@ static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(Crypto::ASN1::Dec
 
     bool is_no_parameter_algorithm = false;
     for (auto const& inner : no_parameter_algorithms) {
-        if (inner.span() == algorithm.span()) {
+        if (inner == algorithm.span()) {
             is_no_parameter_algorithm = true;
         }
     }
@@ -381,7 +394,7 @@ ErrorOr<SubjectPublicKey> parse_subject_public_key_info(Crypto::ASN1::Decoder& d
 
     // https://datatracker.ietf.org/doc/html/rfc8410#section-9
     // For all of the OIDs, the parameters MUST be absent.
-    Array<Array<int, 7>, 5> no_parameter_algorithms = {
+    constexpr static Array<Span<int const>, 5> no_parameter_algorithms = {
         ec_public_key_encryption_oid,
         x25519_oid,
         x448_oid,
@@ -390,7 +403,7 @@ ErrorOr<SubjectPublicKey> parse_subject_public_key_info(Crypto::ASN1::Decoder& d
     };
 
     for (auto const& inner : no_parameter_algorithms) {
-        if (public_key.algorithm.identifier.span() == inner.span()) {
+        if (public_key.algorithm.identifier.span() == inner) {
             // Note: Raw key is already stored, so we can just exit out at this point.
             EXIT_SCOPE();
             return public_key;
@@ -451,7 +464,7 @@ ErrorOr<PrivateKey> parse_private_key_info(Crypto::ASN1::Decoder& decoder, Vecto
 
     // https://datatracker.ietf.org/doc/html/rfc8410#section-9
     // For all of the OIDs, the parameters MUST be absent.
-    Array<Array<int, 7>, 5> no_parameter_algorithms = {
+    constexpr static Array<Span<int const>, 5> no_parameter_algorithms = {
         ec_public_key_encryption_oid,
         x25519_oid,
         x448_oid,
@@ -460,7 +473,7 @@ ErrorOr<PrivateKey> parse_private_key_info(Crypto::ASN1::Decoder& decoder, Vecto
     };
 
     for (auto const& inner : no_parameter_algorithms) {
-        if (private_key.algorithm.identifier.span() == inner.span()) {
+        if (private_key.algorithm.identifier.span() == inner) {
             // Note: Raw key is already stored, so we can just exit out at this point.
             EXIT_SCOPE();
             return private_key;

+ 10 - 30
Libraries/LibCrypto/Certificate/Certificate.h

@@ -31,40 +31,20 @@ constexpr static Array<int, 7>
     ecdsa_with_sha256_encryption_oid { 1, 2, 840, 10045, 4, 3, 2 },
     ecdsa_with_sha384_encryption_oid { 1, 2, 840, 10045, 4, 3, 3 },
     ecdsa_with_sha512_encryption_oid { 1, 2, 840, 10045, 4, 3, 4 },
-    ec_public_key_encryption_oid { 1, 2, 840, 10045, 2, 1 },
-    x25519_oid { 1, 3, 101, 110 },
-    x448_oid { 1, 3, 101, 111 },
-    ed25519_oid { 1, 3, 101, 112 },
-    ed448_oid { 1, 3, 101, 113 },
-    secp256r1_oid { 1, 2, 840, 10045, 3, 1, 7 },
-    secp384r1_oid { 1, 3, 132, 0, 34 },
-    secp521r1_oid { 1, 3, 132, 0, 35 };
-
-constexpr static Array<Array<int, 7>, 12> known_algorithm_identifiers {
-    rsa_encryption_oid,
-    rsa_md5_encryption_oid,
-    rsa_sha1_encryption_oid,
-    rsa_sha256_encryption_oid,
-    rsa_sha384_encryption_oid,
-    rsa_sha512_encryption_oid,
-    ecdsa_with_sha256_encryption_oid,
-    ecdsa_with_sha384_encryption_oid,
-    ec_public_key_encryption_oid,
-    x25519_oid,
-    ed25519_oid,
-    x448_oid,
-};
+    secp256r1_oid { 1, 2, 840, 10045, 3, 1, 7 };
 
-constexpr static Array<int, 7>
-    curve_ansip384r1 { 1, 3, 132, 0, 34 },
-    curve_prime256 { 1, 2, 840, 10045, 3, 1, 7 };
+constexpr static Array<int, 6>
+    ec_public_key_encryption_oid { 1, 2, 840, 10045, 2, 1 };
 
-constexpr static Array<Array<int, 7>, 9> known_curve_identifiers {
-    curve_ansip384r1,
-    curve_prime256
-};
+constexpr static Array<int, 5>
+    secp384r1_oid { 1, 3, 132, 0, 34 },
+    secp521r1_oid { 1, 3, 132, 0, 35 };
 
 constexpr static Array<int, 4>
+    x25519_oid { 1, 3, 101, 110 },
+    x448_oid { 1, 3, 101, 111 },
+    ed25519_oid { 1, 3, 101, 112 },
+    ed448_oid { 1, 3, 101, 113 },
     key_usage_oid { 2, 5, 29, 15 },
     subject_alternative_name_oid { 2, 5, 29, 17 },
     issuer_alternative_name_oid { 2, 5, 29, 18 },

+ 2 - 2
Libraries/LibTLS/TLSv12.cpp

@@ -597,9 +597,9 @@ ErrorOr<Vector<Certificate>> DefaultRootCACertificates::parse_pem_root_certifica
 
 ErrorOr<SupportedGroup> oid_to_curve(Vector<int> curve)
 {
-    if (curve == Crypto::Certificate::curve_ansip384r1)
+    if (curve == Crypto::Certificate::secp384r1_oid)
         return SupportedGroup::SECP384R1;
-    if (curve == Crypto::Certificate::curve_prime256)
+    if (curve == Crypto::Certificate::secp256r1_oid)
         return SupportedGroup::SECP256R1;
 
     return AK::Error::from_string_literal("Unknown curve oid");

+ 4 - 24
Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp

@@ -3144,7 +3144,7 @@ WebIDL::ExceptionOr<GC::Ref<JS::Object>> ECDH::export_key(Bindings::KeyFormat fo
                 [&](::Crypto::PK::ECPublicKey<> const& public_key) -> ErrorOr<ByteBuffer> {
                     auto public_key_bytes = TRY(public_key.to_uncompressed());
 
-                    Array<int, 7> ec_params;
+                    Span<int const> ec_params;
                     if (algorithm.named_curve() == "P-256"sv)
                         ec_params = ::Crypto::Certificate::secp256r1_oid;
                     else if (algorithm.named_curve() == "P-384"sv)
@@ -3154,17 +3154,7 @@ WebIDL::ExceptionOr<GC::Ref<JS::Object>> ECDH::export_key(Bindings::KeyFormat fo
                     else
                         VERIFY_NOT_REACHED();
 
-                    // NOTE: we store OIDs as 7 bytes, but they might be shorter
-                    size_t trailing_zeros = 0;
-                    for (size_t i = ec_params.size() - 1; i > 0; --i) {
-                        if (ec_params[i] == 0)
-                            ++trailing_zeros;
-                        else
-                            break;
-                    }
-
-                    auto ec_public_key_oid = ::Crypto::Certificate::ec_public_key_encryption_oid.span().trim(6);
-                    return TRY(::Crypto::PK::wrap_in_subject_public_key_info(public_key_bytes, ec_public_key_oid, ec_params.span().trim(ec_params.size() - trailing_zeros)));
+                    return TRY(::Crypto::PK::wrap_in_subject_public_key_info(public_key_bytes, ::Crypto::Certificate::ec_public_key_encryption_oid, ec_params));
                 },
                 [](auto) -> ErrorOr<ByteBuffer> {
                     VERIFY_NOT_REACHED();
@@ -3221,7 +3211,7 @@ WebIDL::ExceptionOr<GC::Ref<JS::Object>> ECDH::export_key(Bindings::KeyFormat fo
             // NOTE: everything above happens in wrap_in_private_key_info
             auto maybe_data = handle.visit(
                 [&](::Crypto::PK::ECPrivateKey<> const& private_key) -> ErrorOr<ByteBuffer> {
-                    Array<int, 7> ec_params;
+                    Span<int const> ec_params;
                     if (algorithm.named_curve() == "P-256"sv)
                         ec_params = ::Crypto::Certificate::secp256r1_oid;
                     else if (algorithm.named_curve() == "P-384"sv)
@@ -3231,17 +3221,7 @@ WebIDL::ExceptionOr<GC::Ref<JS::Object>> ECDH::export_key(Bindings::KeyFormat fo
                     else
                         VERIFY_NOT_REACHED();
 
-                    // NOTE: we store OIDs as 7 bytes, but they might be shorter
-                    size_t trailing_zeros = 0;
-                    for (size_t i = ec_params.size() - 1; i > 0; --i) {
-                        if (ec_params[i] == 0)
-                            ++trailing_zeros;
-                        else
-                            break;
-                    }
-
-                    auto ec_public_key_oid = ::Crypto::Certificate::ec_public_key_encryption_oid.span().trim(6);
-                    return TRY(::Crypto::PK::wrap_in_private_key_info(private_key, ec_public_key_oid, ec_params.span().trim(ec_params.size() - trailing_zeros)));
+                    return TRY(::Crypto::PK::wrap_in_private_key_info(private_key, ::Crypto::Certificate::ec_public_key_encryption_oid, ec_params));
                 },
                 [](auto) -> ErrorOr<ByteBuffer> {
                     VERIFY_NOT_REACHED();

+ 7 - 7
Tests/LibWeb/Text/expected/wpt-import/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.txt

@@ -6,8 +6,8 @@ Rerun
 
 Found 40 tests
 
-25 Pass
-15 Fail
+30 Pass
+10 Fail
 Details
 Result	Test Name	MessagePass	setup - define tests	
 Fail	P-521 good parameters	
@@ -16,12 +16,12 @@ Fail	P-521 short result
 Fail	P-521 non-multiple of 8 bits	
 Pass	P-521 missing public curve	
 Pass	P-521 public property of algorithm is not a CryptoKey	
-Fail	P-521 mismatched curves	
+Pass	P-521 mismatched curves	
 Fail	P-521 public property of algorithm is not an ECDSA public key	Cannot access property "publicKey" on null object "ecdsaKeyPairs[namedCurve]"
-Fail	P-521 no deriveBits usage for base key	
-Fail	P-521 base key is not a private key	
-Fail	P-521 public property value is a private key	
-Fail	P-521 public property value is a secret key	
+Pass	P-521 no deriveBits usage for base key	
+Pass	P-521 base key is not a private key	
+Pass	P-521 public property value is a private key	
+Pass	P-521 public property value is a secret key	
 Fail	P-521 asking for too many bits	
 Pass	P-256 good parameters	
 Pass	P-256 mixed case parameters	

+ 7 - 7
Tests/LibWeb/Text/expected/wpt-import/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.txt

@@ -6,20 +6,20 @@ Rerun
 
 Found 31 tests
 
-23 Pass
-8 Fail
+28 Pass
+3 Fail
 Details
 Result	Test Name	MessagePass	setup - define tests	
 Fail	P-521 good parameters	
 Fail	P-521 mixed case parameters	
 Pass	P-521 missing public curve	
 Pass	P-521 public property of algorithm is not a CryptoKey	
-Fail	P-521 mismatched curves	
+Pass	P-521 mismatched curves	
 Fail	P-521 public property of algorithm is not an ECDSA public key	Cannot access property "publicKey" on null object "ecdsaKeyPairs[namedCurve]"
-Fail	P-521 no deriveKey usage for base key	
-Fail	P-521 base key is not a private key	
-Fail	P-521 public property value is a private key	
-Fail	P-521 public property value is a secret key	
+Pass	P-521 no deriveKey usage for base key	
+Pass	P-521 base key is not a private key	
+Pass	P-521 public property value is a private key	
+Pass	P-521 public property value is a secret key	
 Pass	P-256 good parameters	
 Pass	P-256 mixed case parameters	
 Pass	P-256 missing public curve	

+ 11 - 11
Tests/LibWeb/Text/expected/wpt-import/WebCryptoAPI/import_export/ec_importKey.https.any.txt

@@ -6,8 +6,8 @@ Rerun
 
 Found 246 tests
 
-90 Pass
-144 Fail
+97 Pass
+137 Fail
 12 Optional Feature Unsupported
 Details
 Result	Test Name	MessageFail	Good parameters: P-256 bits (spki, buffer(91), {name: ECDSA, namedCurve: P-256}, true, [verify])	
@@ -217,7 +217,7 @@ Pass	Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, n
 Pass	ECDH any JWK alg: P-384 bits (jwk, object(kty, crv, x, y, d, alg), {name: ECDH, namedCurve: P-384}, false, [deriveKey, deriveBits, deriveKey, deriveBits])	
 Pass	Empty Usages: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [])	
 Fail	Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, true, [])	
-Optional Feature Unsupported	Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, true, [])	Compressed point format not supported: DataError: Error parsing subjectPublicKeyInfo: [ "SubjectPublicKeyInfo"sv, "AlgorithmIdentifier"sv ]: Unknown named curve [ 1, 3, 132, 0, 35, 0, 0 ]
+Optional Feature Unsupported	Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, true, [])	Compressed point format not supported: DataError: Unsupported key format
 Fail	Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-521}, true, [])	
 Pass	ECDH any JWK alg: P-521 bits (jwk, object(kty, crv, x, y, alg), {name: ECDH, namedCurve: P-521}, true, [])	
 Fail	Good parameters: P-521 bits (raw, buffer(133), {name: ECDH, namedCurve: P-521}, true, [])	
@@ -226,7 +226,7 @@ Fail	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P
 Fail	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey])	
 Fail	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits])	
 Fail	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits])	
-Fail	Empty Usages: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [])	
+Pass	Empty Usages: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [])	
 Fail	Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [deriveKey])	
 Pass	ECDH any JWK alg: P-521 bits (jwk, object(kty, crv, x, y, d, alg), {name: ECDH, namedCurve: P-521}, true, [deriveKey])	
 Fail	Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey])	
@@ -236,17 +236,17 @@ Pass	ECDH any JWK alg: P-521 bits (jwk, object(kty, crv, x, y, d, alg), {name: E
 Fail	Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits])	
 Pass	ECDH any JWK alg: P-521 bits (jwk, object(kty, crv, x, y, d, alg), {name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits])	
 Pass	Empty Usages: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [])	
-Fail	Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, false, [])	
-Optional Feature Unsupported	Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, false, [])	Compressed point format not supported: DataError: Error parsing subjectPublicKeyInfo: [ "SubjectPublicKeyInfo"sv, "AlgorithmIdentifier"sv ]: Unknown named curve [ 1, 3, 132, 0, 35, 0, 0 ]
+Pass	Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, false, [])	
+Optional Feature Unsupported	Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, false, [])	Compressed point format not supported: DataError: Unsupported key format
 Pass	Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-521}, false, [])	
 Pass	ECDH any JWK alg: P-521 bits (jwk, object(kty, crv, x, y, alg), {name: ECDH, namedCurve: P-521}, false, [])	
 Pass	Good parameters: P-521 bits (raw, buffer(133), {name: ECDH, namedCurve: P-521}, false, [])	
 Optional Feature Unsupported	Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDH, namedCurve: P-521}, false, [])	Compressed point format not supported: DataError: Invalid key size
-Fail	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveKey])	
-Fail	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey])	
-Fail	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits])	
-Fail	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveKey, deriveBits, deriveKey, deriveBits])	
-Fail	Empty Usages: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [])	
+Pass	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveKey])	
+Pass	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey])	
+Pass	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits])	
+Pass	Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveKey, deriveBits, deriveKey, deriveBits])	
+Pass	Empty Usages: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [])	
 Pass	Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, false, [deriveKey])	
 Pass	ECDH any JWK alg: P-521 bits (jwk, object(kty, crv, x, y, d, alg), {name: ECDH, namedCurve: P-521}, false, [deriveKey])	
 Pass	Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey])	

+ 3 - 4
Tests/LibWeb/Text/expected/wpt-import/WebCryptoAPI/import_export/ec_importKey_failures_ECDH.https.any.txt

@@ -6,8 +6,7 @@ Rerun
 
 Found 608 tests
 
-606 Pass
-2 Fail
+608 Pass
 Details
 Result	Test Name	MessagePass	Bad usages: importKey(spki, {name: ECDH, namedCurve: P-256}, true, [encrypt])	
 Pass	Bad usages: importKey(spki, {name: ECDH, namedCurve: P-256}, false, [encrypt])	
@@ -473,8 +472,8 @@ Pass	Empty usages: importKey(pkcs8, {name: ECDH, namedCurve: P-384}, true, [])
 Pass	Empty usages: importKey(pkcs8, {name: ECDH, namedCurve: P-384}, false, [])	
 Pass	Empty usages: importKey(jwk(private), {name: ECDH, namedCurve: P-384}, true, [])	
 Pass	Empty usages: importKey(jwk(private), {name: ECDH, namedCurve: P-384}, false, [])	
-Fail	Empty usages: importKey(pkcs8, {name: ECDH, namedCurve: P-521}, true, [])	
-Fail	Empty usages: importKey(pkcs8, {name: ECDH, namedCurve: P-521}, false, [])	
+Pass	Empty usages: importKey(pkcs8, {name: ECDH, namedCurve: P-521}, true, [])	
+Pass	Empty usages: importKey(pkcs8, {name: ECDH, namedCurve: P-521}, false, [])	
 Pass	Empty usages: importKey(jwk(private), {name: ECDH, namedCurve: P-521}, true, [])	
 Pass	Empty usages: importKey(jwk(private), {name: ECDH, namedCurve: P-521}, false, [])	
 Pass	Bad key length: importKey(spki, {name: ECDH, namedCurve: P-256}, true, [])