Skip to content

Commit 0a64399

Browse files
authored
feat(crypto): Add SPKI format support for ECDSA and RSA keys (#277)
* feat: Add SPKI format support for ECDSA and RSA keys - Implement SPKI import for ECDSA (P-256, P-384, P-521) - Implement SPKI import for RSA-PKCS1-v1_5 - Add integration tests for SPKI key import - Enforce verify-only usage for SPKI public keys * Result of wpt-update * Remove redundant empty check * Return false on signature length mismatch * Updated wpt results
1 parent 275e7d4 commit 0a64399

4 files changed

Lines changed: 698 additions & 452 deletions

File tree

builtins/web/crypto/crypto-algorithm.cpp

Lines changed: 146 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -979,8 +979,7 @@ JS::Result<bool> CryptoAlgorithmECDSA_Sign_Verify::verify(JSContext *cx, JS::Han
979979

980980
size_t coordSize = num_bits_to_bytes(keySize.unwrap());
981981
if (signature.size() != coordSize * 2) {
982-
DOMException::raise(cx, "SubtleCrypto.verify: failed to verify", "OperationError");
983-
return JS::Result<bool>(JS::Error());
982+
return false;
984983
}
985984

986985
BignumPtr r(BN_bin2bn(signature.data(), coordSize, nullptr));
@@ -1742,8 +1741,97 @@ JSObject *CryptoAlgorithmECDSA_Import::importKey(JSContext *cx, CryptoKeyFormat
17421741
auto ecKey = CryptoKeyECComponents::createPrivate(x_sv, y_sv, d_sv);
17431742
return CryptoKey::createECDSA(cx, this, std::move(ecKey), extractable, usages);
17441743
}
1745-
case CryptoKeyFormat::Raw:
17461744
case CryptoKeyFormat::Spki: {
1745+
if (!usages.canOnlyVerify()) {
1746+
DOMException::raise(cx, "SPKI public keys only support 'verify' operations", "SyntaxError");
1747+
return nullptr;
1748+
}
1749+
1750+
auto keyBytes = std::get<std::span<uint8_t>>(key_data);
1751+
const uint8_t *data = keyBytes.data();
1752+
1753+
EvpPkeyPtr pkey(d2i_PUBKEY(nullptr, &data, keyBytes.size()));
1754+
if (!pkey) {
1755+
DOMException::raise(cx, "Invalid SPKI key data", "DataError");
1756+
return nullptr;
1757+
}
1758+
1759+
if (EVP_PKEY_id(pkey.get()) != EVP_PKEY_EC) {
1760+
DOMException::raise(cx, "SPKI key is not an EC key", "DataError");
1761+
return nullptr;
1762+
}
1763+
1764+
char curve_name[64];
1765+
size_t curve_name_len = sizeof(curve_name);
1766+
if (EVP_PKEY_get_utf8_string_param(pkey.get(), OSSL_PKEY_PARAM_GROUP_NAME, curve_name,
1767+
sizeof(curve_name), &curve_name_len) == 0) {
1768+
DOMException::raise(cx, "Failed to get EC curve name", "DataError");
1769+
return nullptr;
1770+
}
1771+
1772+
std::string curveName(curve_name, curve_name_len);
1773+
NamedCurve actualCurve;
1774+
if (curveName == "prime256v1") {
1775+
actualCurve = NamedCurve::P256;
1776+
} else if (curveName == "secp384r1") {
1777+
actualCurve = NamedCurve::P384;
1778+
} else if (curveName == "secp521r1") {
1779+
actualCurve = NamedCurve::P521;
1780+
} else {
1781+
DOMException::raise(cx, "Unsupported curve in SPKI key", "DataError");
1782+
return nullptr;
1783+
}
1784+
1785+
if (actualCurve != this->namedCurve) {
1786+
DOMException::raise(cx, "SPKI curve does not match expected curve", "DataError");
1787+
return nullptr;
1788+
}
1789+
1790+
BIGNUM *x_raw = nullptr;
1791+
BIGNUM *y_raw = nullptr;
1792+
1793+
if ((EVP_PKEY_get_bn_param(pkey.get(), OSSL_PKEY_PARAM_EC_PUB_X, &x_raw) == 0) ||
1794+
(EVP_PKEY_get_bn_param(pkey.get(), OSSL_PKEY_PARAM_EC_PUB_Y, &y_raw) == 0)) {
1795+
DOMException::raise(cx, "Failed to extract EC parameters", "DataError");
1796+
return nullptr;
1797+
}
1798+
1799+
BignumPtr x(x_raw);
1800+
BignumPtr y(y_raw);
1801+
1802+
if (!x || !y) {
1803+
DOMException::raise(cx, "Invalid EC public key", "DataError");
1804+
return nullptr;
1805+
}
1806+
1807+
size_t coordSize = 0;
1808+
switch (actualCurve) {
1809+
case NamedCurve::P256:
1810+
coordSize = 32;
1811+
break;
1812+
case NamedCurve::P384:
1813+
coordSize = 48;
1814+
break;
1815+
case NamedCurve::P521:
1816+
coordSize = 66;
1817+
break;
1818+
}
1819+
1820+
auto [x_bytes, x_size] = to_bytes_expand(cx, x.get(), coordSize);
1821+
auto [y_bytes, y_size] = to_bytes_expand(cx, y.get(), coordSize);
1822+
1823+
if (!x_bytes || !y_bytes) {
1824+
JS_ReportOutOfMemory(cx);
1825+
return nullptr;
1826+
}
1827+
1828+
std::string_view x_sv(reinterpret_cast<const char *>(x_bytes.get()), x_size);
1829+
std::string_view y_sv(reinterpret_cast<const char *>(y_bytes.get()), y_size);
1830+
1831+
auto ecKey = CryptoKeyECComponents::createPublic(x_sv, y_sv);
1832+
return CryptoKey::createECDSA(cx, this, std::move(ecKey), extractable, usages);
1833+
}
1834+
case CryptoKeyFormat::Raw: {
17471835
MOZ_ASSERT(false);
17481836
// TODO finish this
17491837
}
@@ -1766,16 +1854,16 @@ JSObject *CryptoAlgorithmECDSA_Import::importKey(JSContext *cx, CryptoKeyFormat
17661854
data = jwk.release();
17671855
break;
17681856
}
1769-
case CryptoKeyFormat::Pkcs8: {
1857+
case CryptoKeyFormat::Pkcs8:
1858+
case CryptoKeyFormat::Spki: {
17701859
std::optional<std::span<uint8_t>> buffer = value_to_buffer(cx, key_data, "");
17711860
if (!buffer.has_value()) {
17721861
return nullptr;
17731862
}
17741863
data = buffer.value();
17751864
break;
17761865
}
1777-
case CryptoKeyFormat::Raw:
1778-
case CryptoKeyFormat::Spki: {
1866+
case CryptoKeyFormat::Raw: {
17791867
// TODO finish this
17801868
DOMException::raise(cx, "Supplied format is not yet supported", "NotSupportedError");
17811869
return nullptr;
@@ -2113,8 +2201,58 @@ JSObject *CryptoAlgorithmRSASSA_PKCS1_v1_5_Import::importKey(JSContext *cx, Cryp
21132201
return CryptoKey::createRSA(cx, this, std::move(rsa_key), extractable, usages);
21142202
}
21152203
case CryptoKeyFormat::Spki: {
2116-
// TODO: Add implementations for these
2117-
[[fallthrough]];
2204+
if (!usages.isEmpty() && !usages.canOnlyVerify()) {
2205+
DOMException::raise(cx, "SPKI public keys only support 'verify' operations", "SyntaxError");
2206+
return nullptr;
2207+
}
2208+
2209+
auto keyBytes = std::get<std::span<uint8_t>>(key_data);
2210+
const uint8_t *data = keyBytes.data();
2211+
2212+
EvpPkeyPtr pkey(d2i_PUBKEY(nullptr, &data, keyBytes.size()));
2213+
if (!pkey) {
2214+
DOMException::raise(cx, "Invalid SPKI key data", "DataError");
2215+
return nullptr;
2216+
}
2217+
2218+
if (EVP_PKEY_id(pkey.get()) != EVP_PKEY_RSA) {
2219+
DOMException::raise(cx, "SPKI key is not an RSA key", "DataError");
2220+
return nullptr;
2221+
}
2222+
2223+
// Extract RSA public key parameters (n and e)
2224+
BIGNUM *n_raw = nullptr;
2225+
BIGNUM *e_raw = nullptr;
2226+
2227+
if ((EVP_PKEY_get_bn_param(pkey.get(), OSSL_PKEY_PARAM_RSA_N, &n_raw) == 0) ||
2228+
(EVP_PKEY_get_bn_param(pkey.get(), OSSL_PKEY_PARAM_RSA_E, &e_raw) == 0)) {
2229+
DOMException::raise(cx, "Failed to extract RSA parameters", "DataError");
2230+
return nullptr;
2231+
}
2232+
2233+
BignumPtr n(n_raw);
2234+
BignumPtr e(e_raw);
2235+
2236+
if (!n || !e) {
2237+
DOMException::raise(cx, "Invalid RSA public key", "DataError");
2238+
return nullptr;
2239+
}
2240+
2241+
// Convert parameters to byte arrays
2242+
auto [modulus_bytes, modulus_size] = to_bytes_expand(cx, n.get(), 0);
2243+
auto [exponent_bytes, exponent_size] = to_bytes_expand(cx, e.get(), 0);
2244+
2245+
if (!modulus_bytes || !exponent_bytes) {
2246+
JS_ReportOutOfMemory(cx);
2247+
return nullptr;
2248+
}
2249+
2250+
std::string_view modulus_sv(reinterpret_cast<const char *>(modulus_bytes.get()), modulus_size);
2251+
std::string_view exponent_sv(reinterpret_cast<const char *>(exponent_bytes.get()), exponent_size);
2252+
2253+
// Create RSA public key
2254+
auto rsa_key = CryptoKeyRSAComponents::createPublic(modulus_sv, exponent_sv);
2255+
return CryptoKey::createRSA(cx, this, std::move(rsa_key), extractable, usages);
21182256
}
21192257
default: {
21202258
DOMException::raise(cx, "Supplied format is not supported", "DataError");

tests/integration/crypto/crypto.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,27 @@ function base64ToArrayBuffer(b64) {
7575
const ecdsaP256Pkcs8 = base64ToArrayBuffer(
7676
`MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg9+kCK7f6pqJhDk71sqDp+c0R6Y8h5Zq1Yzk8l6aULSehRANCAATmqlo5vDVhxTExquFDjVFNDdjiODbfvZmruJQhJO9JIl/VYdSOlQtLcgEzShv+MJ88HqvxPNlkPrKLDMejB1BE`,
7777
);
78+
const ecdsaP256Spki = base64ToArrayBuffer(
79+
`MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4P7+DJBk6R8R6HRSDLaakl0k83D+MYGqLUEO2DcyB8cAZvGxJRYDakQZuQc/BpYgPTs/C4u4nGr2sQ08cV87xQ==`,
80+
);
7881
const ecdsaP384Pkcs8 = base64ToArrayBuffer(
7982
`MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBUiVVDYE7TA1iib5lEUReaejNpqSuv1hmYYRRsm9zHIslS+z9YjIjMe9UP9pwuOBOhZANiAATv3ew0tmfIjO4rcKB4CirOjvTO+cZBOQpizR+oNnMhhcaFGpewkUzpEQ/du893jA5kANEtzKsplaIAql16zDwr15e8YA73ChHv1RLzapqFHnmD3jbYTzYpEaWlkUDTTWI=`,
8083
);
84+
const ecdsaP384Spki = base64ToArrayBuffer(
85+
`MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEsKinmo/3Ti72/i4papPRvi1DKCe+Cd1N+4osN3OeVYe7KmzfTBX7+deLI1bu9TzXm9VeIa7+omKPXBrLVBB3BN/U3eQW097jG9BX4+91rwW4i/vESlxCGSbb9FhLfxxw`,
86+
);
8187
const ecdsaP521Pkcs8 = base64ToArrayBuffer(
8288
`MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIAGBugOxmjib54TudV/c8teIoAKTC0lYPqgphDS1EEqpxp6IPKQFRBISB6GcxyXHBfqgDv4uVYy2BECzdgRmaEzKihgYkDgYYABAABos1qChbTBstc+4EBpivvNkVy9I1eVQAJhoFEail50sxob/1RMDBYO744Xa2MZz/gssUnVwvJpPmXhDa86omB5gEBLsJ77j3MaY7cZ3ZGL1X2fCWL5VjqxrMj9IQ7N+qrCD86WWnBHa49TnuLHkF+Dw0qe2S3QsmbM8zJ5+o7t1pWBA==`,
8389
);
90+
const ecdsaP521Spki = base64ToArrayBuffer(
91+
`MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBy8hKSiiCilqsLQc9/a2uzv9jVruRvz4T/+ftCXqTXPPtVzuVMOupiV92RUAP/1cbordlIbmRHcHESZ3PKENoSxQAajLUC+7f08O4kCc/hrwT5DYGuSJYEhXsFIVzszEOAOxgNo3KquhpQZetawTeiGBPoKAMe7DFvMQ7MbzvNIHEZhg=`,
92+
);
8493
const rsa2048Pkcs8 = base64ToArrayBuffer(
8594
`MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCRE7mySLjyeokRW/J5qFKc1HSNg/1sbk482ETmiiGUa+537x9H2WqBJ4/ZjQq05LwevKWYuwMW/pAImnwnnIetQ+VN5iAMmo3A1ksIKx+32gQV9DXmK9QI5mYzIH8CJOTEZUlljhrZ4j1yteFtRXD0D8Tr7z+54FO6qISaVGgrWLfGqcBehXmKrf0Iu4oQ3qa4QTDagQU+CVseD5dau5WG16UEJu9tbzQWjnKhuMPVo3vq0/c9pqsJjkGL2AhOBLgpnuWgsXEqhm7ztd5ueuHfbwQCeqjYOwk5j9Bcu6uvTQ8b3fjZhAv2mSnciyCjsl+oZ75fpTZ3ymsHDYXKKyszAgMBAAECggEAEMYoluIMrFCZr42jjAh3wNVZwpELyLE6T5Or58H53vjZwjk+MycCxvsliUBjCAZYb+9c8DtTQKHfUndWOphBIbnzdd3RP9PQ5wZ/92pRCQdmqIkrgDj6E6tcDrZHqR5N6x1Q7rKPDTk45J39+g3o4Pc/zA3GHv4+gBsC9fsjbjtvq5DCO0tqmzKWAe6CtX0JnHiumqv9WD2h5ApXqDfrNdwo+nqYzuA3spAk+yAsEssqGW+2+hK0wOhl/75Yo762sAkR+9W8KWRh2TDWyUSIokcKypjokAYdFkT4MCP7o3FZg/YShLgK6EsulrPBKtFkU28gP25w5OqcK/krsDTf/QKBgQDJxKVw5iE1u7EBAYHOCC/EgKL522HaDZEQa1g8mWYDvv0QohyPdR/om19Xcdyo4RpSXxJSZvO//hBwJ6h8gbF1fb0JducMCJKR8qxYgSdCs52EoQwtJkOnsCQ1L69TEDHW31hHTAvwtTPPyaKzoD47yh03Gv2Qtqw7O4dLnqr5LQKBgQC4EkCn6mQ8BHZQSRZXPRuhuQ1pvtPDAgRw8/IZPttkJUnaewV7vdQQfAReHwwFgN4Qz/1tkyh1lxUw+qHTP6tn4FcogH2NjRkI4yYSVKlrjiQy9LlcS4bO5noigwpK9VL3Dl65YXaQpPAoiH/M7KoJuadcftMvMYSVbpsrAUSx3wKBgAfYMWZ2TAw+w976JAXSo6jMJ4n3UZKcvGsbAU8515GFt2kSJHIfZ6IviEFqF94pAlD5iUjS398zDYiOwio1EKU0wki/6rO5EZnDCZhXTSN2wEULzeFjf3Xhj0bSF8ru8kEcZd4/wqcVJHKLsFuzezfv37rovbsGnyOeaOAzxwnxAoGANdkBGR40nGohwnLfGj5CKxlblyfAAzg/3FtA46nDvJQ7+rIqdHyf4QKmtHIYrjN4wypVVQzLtTqxdFadqJLjrcuvM6YDFLnGLRdmN86UkWZPqKh24U0m7rf12srC5BLIZoXJqCme6cmWiAUGfght5dJt510iope11ZE5y2bflbkCgYEApcgQs8TvOWxRGSPdgd7pz2TXtgs+J17T0X+h/RqP7S7CxFAJ01loFCswA1Gl/Kdw0ShdXEMXOHLXTyVOy2q1suBfT5bb5nQh9GnYr96Cs4qPqbK/MwniREeJLpGLW3COHPhNQIZG2L4mSpkA+07UOMcQF+BwuoVnDOhUs8cNEuo=`,
8695
);
96+
const rsa2048Spki = base64ToArrayBuffer(
97+
`MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvuj+4WNu+G/s+90tjtLBEXpaVQHFOvVBzZ/vMplfYMF1hI5X0iFJlyV06qNCCTaEtNzbzueJfKWzoar6cxzGCumvquXXLIZ/Gg9y9hOwotakJBoE5imhZ12Z37SgRUUC8TkCKyh1C+PCwcf8W9cOFT0RUg82ed5ByRM0VEV4TvUngZH61nu02zUg/fr7HUDIj7e6N/0wjtqIiQuc9dzAk1lt7qo47w35w0njGwhE/VuVrSTILmdRvroMt2nZ1O+c054DbiBlqSsXeaW99YGewT0d2RKdLnf0myvDBuQcFqZUnt26nD2Q2DDI17Mo8MaOmQzgrZ5iVufZ8lC86t18iwIDAQAB`,
98+
);
8799
const rsa3072Pkcs8 = base64ToArrayBuffer(
88100
`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`,
89101
);
@@ -1669,6 +1681,102 @@ export const handler = serveTest(async (t) => {
16691681
strictEqual(keyP384.algorithm.name, "ECDSA", "P-384 algorithm");
16701682
strictEqual(keyP521.algorithm.name, "ECDSA", "P-521 algorithm");
16711683
});
1684+
1685+
// SPKI ECDSA Tests
1686+
await t.test("spki-ecdsa-p256", async () => {
1687+
const key = await crypto.subtle.importKey(
1688+
"spki",
1689+
ecdsaP256Spki,
1690+
ecdsaP256Algorithm,
1691+
true,
1692+
["verify"],
1693+
);
1694+
1695+
strictEqual(key instanceof CryptoKey, true, "key instanceof CryptoKey");
1696+
deepStrictEqual(
1697+
key.algorithm,
1698+
{
1699+
name: "ECDSA",
1700+
namedCurve: "P-256",
1701+
},
1702+
"key.algorithm",
1703+
);
1704+
strictEqual(key.extractable, true, "key.extractable");
1705+
strictEqual(key.type, "public", "key.type");
1706+
deepStrictEqual(key.usages, ["verify"], "key.usages");
1707+
});
1708+
1709+
await t.test("spki-ecdsa-p384", async () => {
1710+
const key = await crypto.subtle.importKey(
1711+
"spki",
1712+
ecdsaP384Spki,
1713+
ecdsaP384Algorithm,
1714+
true,
1715+
["verify"],
1716+
);
1717+
1718+
strictEqual(key instanceof CryptoKey, true, "key instanceof CryptoKey");
1719+
deepStrictEqual(
1720+
key.algorithm,
1721+
{
1722+
name: "ECDSA",
1723+
namedCurve: "P-384",
1724+
},
1725+
"key.algorithm",
1726+
);
1727+
strictEqual(key.extractable, true, "key.extractable");
1728+
strictEqual(key.type, "public", "key.type");
1729+
deepStrictEqual(key.usages, ["verify"], "key.usages");
1730+
});
1731+
1732+
await t.test("spki-ecdsa-p521", async () => {
1733+
const key = await crypto.subtle.importKey(
1734+
"spki",
1735+
ecdsaP521Spki,
1736+
ecdsaP521Algorithm,
1737+
true,
1738+
["verify"],
1739+
);
1740+
1741+
strictEqual(key instanceof CryptoKey, true, "key instanceof CryptoKey");
1742+
deepStrictEqual(
1743+
key.algorithm,
1744+
{
1745+
name: "ECDSA",
1746+
namedCurve: "P-521",
1747+
},
1748+
"key.algorithm",
1749+
);
1750+
strictEqual(key.extractable, true, "key.extractable");
1751+
strictEqual(key.type, "public", "key.type");
1752+
deepStrictEqual(key.usages, ["verify"], "key.usages");
1753+
});
1754+
1755+
// SPKI RSA Test
1756+
await t.test("spki-rsa-2048-pkcs1-sha256", async () => {
1757+
const key = await crypto.subtle.importKey(
1758+
"spki",
1759+
rsa2048Spki,
1760+
rsaPkcs1Sha256Algorithm,
1761+
true,
1762+
["verify"],
1763+
);
1764+
1765+
strictEqual(key instanceof CryptoKey, true, "key instanceof CryptoKey");
1766+
deepStrictEqual(
1767+
key.algorithm,
1768+
{
1769+
name: "RSASSA-PKCS1-v1_5",
1770+
hash: { name: "SHA-256" },
1771+
modulusLength: 2048,
1772+
publicExponent: new Uint8Array([1, 0, 1]),
1773+
},
1774+
"key.algorithm",
1775+
);
1776+
strictEqual(key.extractable, true, "key.extractable");
1777+
strictEqual(key.type, "public", "key.type");
1778+
deepStrictEqual(key.usages, ["verify"], "key.usages");
1779+
});
16721780
}
16731781
}
16741782

tests/wpt-harness/expectations/WebCryptoAPI/import_export/ec_importKey.https.any.js.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@
6363
"status": "FAIL"
6464
},
6565
"Good parameters: P-256 bits (spki, buffer(91), {name: ECDSA, namedCurve: P-256}, false, [verify])": {
66-
"status": "FAIL"
66+
"status": "PASS"
6767
},
6868
"Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify])": {
69-
"status": "FAIL"
69+
"status": "PASS"
7070
},
7171
"Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDSA, namedCurve: P-256}, false, [verify])": {
7272
"status": "PASS"
@@ -93,10 +93,10 @@
9393
"status": "FAIL"
9494
},
9595
"Good parameters: P-256 bits (spki, buffer(91), {name: ECDSA, namedCurve: P-256}, false, [verify, verify])": {
96-
"status": "FAIL"
96+
"status": "PASS"
9797
},
9898
"Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify, verify])": {
99-
"status": "FAIL"
99+
"status": "PASS"
100100
},
101101
"Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDSA, namedCurve: P-256}, false, [verify, verify])": {
102102
"status": "PASS"
@@ -189,10 +189,10 @@
189189
"status": "FAIL"
190190
},
191191
"Good parameters: P-384 bits (spki, buffer(120), {name: ECDSA, namedCurve: P-384}, false, [verify])": {
192-
"status": "FAIL"
192+
"status": "PASS"
193193
},
194194
"Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify])": {
195-
"status": "FAIL"
195+
"status": "PASS"
196196
},
197197
"Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDSA, namedCurve: P-384}, false, [verify])": {
198198
"status": "PASS"
@@ -219,10 +219,10 @@
219219
"status": "FAIL"
220220
},
221221
"Good parameters: P-384 bits (spki, buffer(120), {name: ECDSA, namedCurve: P-384}, false, [verify, verify])": {
222-
"status": "FAIL"
222+
"status": "PASS"
223223
},
224224
"Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify, verify])": {
225-
"status": "FAIL"
225+
"status": "PASS"
226226
},
227227
"Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDSA, namedCurve: P-384}, false, [verify, verify])": {
228228
"status": "PASS"
@@ -315,10 +315,10 @@
315315
"status": "FAIL"
316316
},
317317
"Good parameters: P-521 bits (spki, buffer(158), {name: ECDSA, namedCurve: P-521}, false, [verify])": {
318-
"status": "FAIL"
318+
"status": "PASS"
319319
},
320320
"Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify])": {
321-
"status": "FAIL"
321+
"status": "PASS"
322322
},
323323
"Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDSA, namedCurve: P-521}, false, [verify])": {
324324
"status": "PASS"
@@ -345,10 +345,10 @@
345345
"status": "FAIL"
346346
},
347347
"Good parameters: P-521 bits (spki, buffer(158), {name: ECDSA, namedCurve: P-521}, false, [verify, verify])": {
348-
"status": "FAIL"
348+
"status": "PASS"
349349
},
350350
"Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify, verify])": {
351-
"status": "FAIL"
351+
"status": "PASS"
352352
},
353353
"Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDSA, namedCurve: P-521}, false, [verify, verify])": {
354354
"status": "PASS"

0 commit comments

Comments
 (0)