commit b8764182bedeeb78f0f23c009544a49ab071282f
parent 415ea8686f4ad0422d2b0f2b17482750eaa3dcd3
Author: Anna <anna.weine@mozilla.com>
Date: Mon, 27 Oct 2025 17:13:56 +0000
Bug 1971499 - WebCrypto support for compressed points r=jschanck
Differential Revision: https://phabricator.services.mozilla.com/D266695
Diffstat:
2 files changed, 77 insertions(+), 308 deletions(-)
diff --git a/dom/crypto/CryptoKey.cpp b/dom/crypto/CryptoKey.cpp
@@ -1266,18 +1266,8 @@ nsresult CryptoKey::PublicKeyToJwk(SECKEYPublicKey* aPubKey,
}
}
-UniqueSECKEYPublicKey CryptoKey::PublicECKeyFromRaw(
- CryptoBuffer& aKeyData, const nsString& aNamedCurve) {
- UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
- if (!arena) {
- return nullptr;
- }
-
- SECItem rawItem = {siBuffer, nullptr, 0};
- if (!aKeyData.ToSECItem(arena.get(), &rawItem)) {
- return nullptr;
- }
-
+bool PublicKeyHasCorrectLengthAndEncoding(const nsString& aNamedCurve,
+ const SECItem* key) {
uint32_t flen;
if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P256)) {
flen = 32; // bytes
@@ -1286,17 +1276,37 @@ UniqueSECKEYPublicKey CryptoKey::PublicECKeyFromRaw(
} else if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P521)) {
flen = 66; // bytes
} else {
+ return false;
+ }
+
+ // Here we have 2 possible inputs, either we've received an uncompressed point
+ // then the length is 1 + flen (x) + flen (y) and the 0th byte is
+ // EC_POINT_FORM_UNCOMPRESSED or we work with the compressed point then the
+ // length is 1 + flen (x) and the 0th byte is either
+ // EC_POINT_FORM_COMPRESSED_Y0 or EC_POINT_FORM_COMPRESSED_Y1
+
+ bool correctUncompressed = (key->len == 2 * flen + 1) &&
+ (key->data[0] == EC_POINT_FORM_UNCOMPRESSED);
+ bool correctCompressed = (key->len == flen + 1) &&
+ ((key->data[0] == EC_POINT_FORM_COMPRESSED_Y0) ||
+ (key->data[0] == EC_POINT_FORM_COMPRESSED_Y1));
+
+ return correctCompressed || correctUncompressed;
+}
+
+UniqueSECKEYPublicKey CryptoKey::PublicECKeyFromRaw(
+ CryptoBuffer& aKeyData, const nsString& aNamedCurve) {
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ if (!arena) {
return nullptr;
}
- // Check length of uncompressed point coordinates. There are 2 field elements
- // and a leading point form octet (which must EC_POINT_FORM_UNCOMPRESSED).
- if (rawItem.len != (2 * flen + 1)) {
+ SECItem rawItem = {siBuffer, nullptr, 0};
+ if (!aKeyData.ToSECItem(arena.get(), &rawItem)) {
return nullptr;
}
- // No support for compressed points.
- if (rawItem.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+ if (!PublicKeyHasCorrectLengthAndEncoding(aNamedCurve, &rawItem)) {
return nullptr;
}
@@ -1339,6 +1349,24 @@ UniqueSECKEYPublicKey CryptoKey::PublicOKPKeyFromRaw(
return CreateECPublicKey(&rawItem, aNamedCurve);
}
+bool PublicECKeyEncoded(SECKEYPublicKey* aPubKey) {
+ if (!aPubKey) {
+ return false;
+ }
+
+ SECItem* publicValue = &aPubKey->u.ec.publicValue;
+ if (!publicValue || !publicValue->data || publicValue->len == 0) {
+ return false;
+ }
+
+ if (publicValue->data[0] == EC_POINT_FORM_COMPRESSED_Y0 ||
+ publicValue->data[0] == EC_POINT_FORM_COMPRESSED_Y1) {
+ return true;
+ }
+
+ return false;
+}
+
bool CryptoKey::PublicKeyValid(SECKEYPublicKey* aPubKey) {
UniquePK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot.get()) {
@@ -1349,7 +1377,38 @@ bool CryptoKey::PublicKeyValid(SECKEYPublicKey* aPubKey) {
// it is imported into a PKCS#11 module, and returns CK_INVALID_HANDLE
// if it is invalid.
CK_OBJECT_HANDLE id = PK11_ImportPublicKey(slot.get(), aPubKey, PR_FALSE);
- return id != CK_INVALID_HANDLE;
+ if (id == CK_INVALID_HANDLE) {
+ return false;
+ }
+
+ // It is possible that the public key was in the decompressed form
+ // Thus we need to read the attribute to retrieve the key
+ if (aPubKey->keyType == ecKey && PublicECKeyEncoded(aPubKey)) {
+ ScopedAutoSECItem encodedPublicKey;
+ // Independently from whether the key was decompressed or not,
+ // the raw attribute is stored encoded.
+ SECStatus rv = PK11_ReadRawAttribute(PK11_TypePubKey, aPubKey, CKA_EC_POINT,
+ &encodedPublicKey);
+ if (NS_WARN_IF(rv != SECSuccess)) {
+ return false;
+ }
+
+ SECItem decoded;
+ rv = SEC_QuickDERDecodeItem(aPubKey->arena, &decoded,
+ SEC_ASN1_GET(SEC_OctetStringTemplate),
+ &encodedPublicKey);
+ if (NS_WARN_IF(rv != SECSuccess)) {
+ return false;
+ }
+
+ // Updating the public key
+ rv = SECITEM_CopyItem(aPubKey->arena, &aPubKey->u.ec.publicValue, &decoded);
+ if (NS_WARN_IF(rv != SECSuccess)) {
+ return false;
+ }
+ }
+
+ return true;
}
bool CryptoKey::WriteStructuredClone(JSContext* aCX,
diff --git a/testing/web-platform/meta/WebCryptoAPI/import_export/ec_importKey.https.any.js.ini b/testing/web-platform/meta/WebCryptoAPI/import_export/ec_importKey.https.any.js.ini
@@ -1,290 +0,0 @@
-[ec_importKey.https.any.html]
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDH, namedCurve: P-256}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDH, namedCurve: P-256}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDH, namedCurve: P-256}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDH, namedCurve: P-256}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDH, namedCurve: P-384}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDH, namedCurve: P-384}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDH, namedCurve: P-384}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDH, namedCurve: P-384}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDH, namedCurve: P-521}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDH, namedCurve: P-521}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
-
-[ec_importKey.https.any.worker.html]
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDH, namedCurve: P-256}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDH, namedCurve: P-256}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDH, namedCurve: P-256}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDH, namedCurve: P-256}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDH, namedCurve: P-384}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDH, namedCurve: P-384}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDH, namedCurve: P-384}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDH, namedCurve: P-384}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDH, namedCurve: P-521}, true, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDH, namedCurve: P-521}, false, [\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDSA, namedCurve: P-256}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDSA, namedCurve: P-384}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, true, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, true, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED
-
- [Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDSA, namedCurve: P-521}, false, [verify, verify\])]
- expected: PRECONDITION_FAILED