From b91c6381d3a6dc2d3384115af67cef32f22627c7 Mon Sep 17 00:00:00 2001 From: Javier Fernandez Date: Thu, 11 Jul 2024 18:09:21 +0200 Subject: [PATCH] Define the deriveBits length parameter as optional https://bugs.webkit.org/show_bug.cgi?id=276394 Reviewed by NOBODY (OOPS!). The PR#345 [1] to the WebCryptoAPI spec defines now the 'length' parameter as optional, defaulting to 'null'. This change tries to solve a long-standing interoperability issue in the deriveBits operation. This patch implements the required changes in the IDL so that the 'length' parameter is declared as optional, with 'null' as default value when omitted. The affected algorithms (ECDH, HKDF, PBKDF2 and X25519) are adapted to the parameter's new type. The PR#43400 [2] defined tests for the new behavior of the afected algorithms, which they all pass now. [1] https://github.com/w3c/webcrypto/pull/345 [2] https://github.com/web-platform-tests/wpt/pull/43400 * LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt: * LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html: * LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits-expected.txt: * LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits.html: * LayoutTests/crypto/subtle/pbkdf2-derive-bits-malformed-parametrs-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.worker-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any.worker-expected.txt: * Source/WebCore/crypto/CryptoAlgorithm.cpp: (WebCore::CryptoAlgorithm::deriveBits): * Source/WebCore/crypto/CryptoAlgorithm.h: * Source/WebCore/crypto/SubtleCrypto.cpp: (WebCore::SubtleCrypto::deriveKey): (WebCore::SubtleCrypto::deriveBits): * Source/WebCore/crypto/SubtleCrypto.h: * Source/WebCore/crypto/SubtleCrypto.idl: * Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp: (WebCore::CryptoAlgorithmECDH::deriveBits): * Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h: * Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.cpp: (WebCore::CryptoAlgorithmHKDF::deriveBits): * Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.h: * Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.cpp: (WebCore::CryptoAlgorithmPBKDF2::deriveBits): * Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.h: * Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.cpp: (WebCore::CryptoAlgorithmX25519::deriveBits): * Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.h: --- .../derive-bits-malformed-parameters-expected.txt | 1 - .../subtle/derive-bits-malformed-parameters.html | 1 - .../ecdh-derive-bits-length-limits-expected.txt | 6 +++--- .../subtle/ecdh-derive-bits-length-limits.html | 6 +++--- .../derived_bits_length.https.any-expected.txt | 12 ++++++------ ...derived_bits_length.https.any.worker-expected.txt | 12 ++++++------ .../WebCryptoAPI/idlharness.https.any-expected.txt | 2 +- .../idlharness.https.any.worker-expected.txt | 2 +- Source/WebCore/crypto/CryptoAlgorithm.cpp | 2 +- Source/WebCore/crypto/CryptoAlgorithm.h | 2 +- Source/WebCore/crypto/SubtleCrypto.cpp | 4 ++-- Source/WebCore/crypto/SubtleCrypto.h | 2 +- Source/WebCore/crypto/SubtleCrypto.idl | 2 +- .../crypto/algorithms/CryptoAlgorithmECDH.cpp | 6 +++--- .../WebCore/crypto/algorithms/CryptoAlgorithmECDH.h | 2 +- .../crypto/algorithms/CryptoAlgorithmHKDF.cpp | 6 +++--- .../WebCore/crypto/algorithms/CryptoAlgorithmHKDF.h | 2 +- .../crypto/algorithms/CryptoAlgorithmPBKDF2.cpp | 6 +++--- .../crypto/algorithms/CryptoAlgorithmPBKDF2.h | 2 +- .../crypto/algorithms/CryptoAlgorithmX25519.cpp | 6 +++--- .../crypto/algorithms/CryptoAlgorithmX25519.h | 2 +- 21 files changed, 42 insertions(+), 44 deletions(-) diff --git a/LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt b/LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt index 00b0fbd3ea126..263c85320f50f 100644 --- a/LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt +++ b/LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt @@ -5,7 +5,6 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE PASS crypto.subtle.deriveBits() rejected promise with TypeError: Not enough arguments. PASS crypto.subtle.deriveBits(1) rejected promise with TypeError: Not enough arguments. -PASS crypto.subtle.deriveBits(1, 2) rejected promise with TypeError: Not enough arguments. PASS crypto.subtle.deriveBits({ name:"ECDH", public:wrongKey }, wrongKey, 128) rejected promise with InvalidAccessError: CryptoKey doesn't match AlgorithmIdentifier. PASS crypto.subtle.deriveBits({ name:"ECDH", public:wrongKey }, wrongKey, 128) rejected promise with InvalidAccessError: CryptoKey doesn't support bits derivation. PASS successfullyParsed is true diff --git a/LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html b/LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html index 54e41e71e5ab1..740251ddab8eb 100644 --- a/LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html +++ b/LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html @@ -32,7 +32,6 @@ // Not enough arguments. shouldReject('crypto.subtle.deriveBits()'); shouldReject('crypto.subtle.deriveBits(1)'); -shouldReject('crypto.subtle.deriveBits(1, 2)'); crypto.subtle.importKey("raw", rawKey, hmacImportParams, extractable, ["sign", "verify"]).then(function(result) { wrongKey = result; diff --git a/LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits-expected.txt b/LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits-expected.txt index b7209b0c048e0..8cd8a74431f9f 100644 --- a/LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits-expected.txt +++ b/LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits-expected.txt @@ -3,17 +3,17 @@ Test ECDH deriveBits operation for corner-case length values. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS deriveBits(..., 0) successfully derived 256 bits for a P-256 curve +PASS deriveBits(..., 0) successfully derived 0 bits for a P-256 curve PASS deriveBits(..., 8) successfully derived 8 bits for a P-256 curve PASS deriveBits(..., 256) successfully derived 256 bits for a P-256 curve PASS Bit derivations for EC P-256 with minimum and maximum lengths succeeded PASS deriveBits(P256, 256 + 8) rejected promise with OperationError: The operation failed for an operation-specific reason. -PASS deriveBits(..., 0) successfully derived 384 bits for a P-384 curve +PASS deriveBits(..., 0) successfully derived 0 bits for a P-384 curve PASS deriveBits(..., 8) successfully derived 8 bits for a P-384 curve PASS deriveBits(..., 384) successfully derived 384 bits for a P-384 curve PASS Bit derivations for EC P-384 with minimum and maximum lengths succeeded PASS deriveBits(P384, 384 + 8) rejected promise with OperationError: The operation failed for an operation-specific reason. -PASS deriveBits(..., 0) successfully derived 528 bits for a P-521 curve +PASS deriveBits(..., 0) successfully derived 0 bits for a P-521 curve PASS deriveBits(..., 8) successfully derived 8 bits for a P-521 curve PASS deriveBits(..., 528) successfully derived 528 bits for a P-521 curve PASS Bit derivations for EC P-521 with minimum and maximum lengths succeeded diff --git a/LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits.html b/LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits.html index d2a4be2db07e2..39c148f645b68 100644 --- a/LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits.html +++ b/LayoutTests/crypto/subtle/ecdh-derive-bits-length-limits.html @@ -85,7 +85,7 @@ return Promise.resolve().then(function(result) { // P-256 return Promise.all([ - deriveBits(P256, 0, 256), + deriveBits(P256, 0, 0), deriveBits(P256, 8, 8), deriveBits(P256, 256, 256), ]).then(function(result) { @@ -95,7 +95,7 @@ }).then(function(result) { // P-384 return Promise.all([ - deriveBits(P384, 0, 384), + deriveBits(P384, 0, 0), deriveBits(P384, 8, 8), deriveBits(P384, 384, 384), ]).then(function(result) { @@ -111,7 +111,7 @@ // P-521 return Promise.all([ - deriveBits(P521, 0, 528), + deriveBits(P521, 0, 0), deriveBits(P521, 8, 8), deriveBits(P521, 528, 528), ]).then(function(result) { diff --git a/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any-expected.txt index 136c5be6072e0..ce7895eb93e21 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any-expected.txt @@ -4,20 +4,20 @@ PASS HKDF derivation with 256 as 'length' parameter PASS HKDF derivation with 0 as 'length' parameter PASS HKDF derivation with null as 'length' parameter PASS HKDF derivation with undefined as 'length' parameter -FAIL HKDF derivation with omitted as 'length' parameter assert_equals: deriveBits correctly threw OperationError: Not enough arguments expected "OperationError" but got "TypeError" +PASS HKDF derivation with omitted as 'length' parameter PASS PBKDF2 derivation with 256 as 'length' parameter PASS PBKDF2 derivation with 0 as 'length' parameter PASS PBKDF2 derivation with null as 'length' parameter PASS PBKDF2 derivation with undefined as 'length' parameter -FAIL PBKDF2 derivation with omitted as 'length' parameter assert_equals: deriveBits correctly threw OperationError: Not enough arguments expected "OperationError" but got "TypeError" +PASS PBKDF2 derivation with omitted as 'length' parameter PASS ECDH derivation with 256 as 'length' parameter -FAIL ECDH derivation with 0 as 'length' parameter assert_array_equals: Derived bits do not match the expected result. lengths differ, expected array object "" length 0, got object "87,31,26,232,151,28,227,35,250,17,131,137,203,95,65,196,59,61,181,161" length 32 +PASS ECDH derivation with 0 as 'length' parameter PASS ECDH derivation with null as 'length' parameter PASS ECDH derivation with undefined as 'length' parameter -FAIL ECDH derivation with omitted as 'length' parameter promise_test: Unhandled rejection with value: object "TypeError: Not enough arguments" +PASS ECDH derivation with omitted as 'length' parameter PASS X25519 derivation with 256 as 'length' parameter -FAIL X25519 derivation with 0 as 'length' parameter assert_array_equals: Derived bits do not match the expected result. lengths differ, expected array object "" length 0, got object "63,245,136,2,149,247,97,118,8,143,137,228,61,254,190,126,161,149,0,8" length 32 +PASS X25519 derivation with 0 as 'length' parameter PASS X25519 derivation with null as 'length' parameter PASS X25519 derivation with undefined as 'length' parameter -FAIL X25519 derivation with omitted as 'length' parameter promise_test: Unhandled rejection with value: object "TypeError: Not enough arguments" +PASS X25519 derivation with omitted as 'length' parameter diff --git a/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.worker-expected.txt index 136c5be6072e0..ce7895eb93e21 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.worker-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.worker-expected.txt @@ -4,20 +4,20 @@ PASS HKDF derivation with 256 as 'length' parameter PASS HKDF derivation with 0 as 'length' parameter PASS HKDF derivation with null as 'length' parameter PASS HKDF derivation with undefined as 'length' parameter -FAIL HKDF derivation with omitted as 'length' parameter assert_equals: deriveBits correctly threw OperationError: Not enough arguments expected "OperationError" but got "TypeError" +PASS HKDF derivation with omitted as 'length' parameter PASS PBKDF2 derivation with 256 as 'length' parameter PASS PBKDF2 derivation with 0 as 'length' parameter PASS PBKDF2 derivation with null as 'length' parameter PASS PBKDF2 derivation with undefined as 'length' parameter -FAIL PBKDF2 derivation with omitted as 'length' parameter assert_equals: deriveBits correctly threw OperationError: Not enough arguments expected "OperationError" but got "TypeError" +PASS PBKDF2 derivation with omitted as 'length' parameter PASS ECDH derivation with 256 as 'length' parameter -FAIL ECDH derivation with 0 as 'length' parameter assert_array_equals: Derived bits do not match the expected result. lengths differ, expected array object "" length 0, got object "87,31,26,232,151,28,227,35,250,17,131,137,203,95,65,196,59,61,181,161" length 32 +PASS ECDH derivation with 0 as 'length' parameter PASS ECDH derivation with null as 'length' parameter PASS ECDH derivation with undefined as 'length' parameter -FAIL ECDH derivation with omitted as 'length' parameter promise_test: Unhandled rejection with value: object "TypeError: Not enough arguments" +PASS ECDH derivation with omitted as 'length' parameter PASS X25519 derivation with 256 as 'length' parameter -FAIL X25519 derivation with 0 as 'length' parameter assert_array_equals: Derived bits do not match the expected result. lengths differ, expected array object "" length 0, got object "63,245,136,2,149,247,97,118,8,143,137,228,61,254,190,126,161,149,0,8" length 32 +PASS X25519 derivation with 0 as 'length' parameter PASS X25519 derivation with null as 'length' parameter PASS X25519 derivation with undefined as 'length' parameter -FAIL X25519 derivation with omitted as 'length' parameter promise_test: Unhandled rejection with value: object "TypeError: Not enough arguments" +PASS X25519 derivation with omitted as 'length' parameter diff --git a/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any-expected.txt index eab10a61942a6..00b4f5420fc04 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any-expected.txt @@ -49,7 +49,7 @@ PASS SubtleCrypto interface: operation verify(AlgorithmIdentifier, CryptoKey, Bu PASS SubtleCrypto interface: operation digest(AlgorithmIdentifier, BufferSource) PASS SubtleCrypto interface: operation generateKey(AlgorithmIdentifier, boolean, sequence) PASS SubtleCrypto interface: operation deriveKey(AlgorithmIdentifier, CryptoKey, AlgorithmIdentifier, boolean, sequence) -PASS SubtleCrypto interface: operation deriveBits(AlgorithmIdentifier, CryptoKey, unsigned long) +FAIL SubtleCrypto interface: operation deriveBits(AlgorithmIdentifier, CryptoKey, unsigned long) assert_equals: property has wrong .length expected 3 but got 2 PASS SubtleCrypto interface: operation importKey(KeyFormat, (BufferSource or JsonWebKey), AlgorithmIdentifier, boolean, sequence) PASS SubtleCrypto interface: operation exportKey(KeyFormat, CryptoKey) PASS SubtleCrypto interface: operation wrapKey(KeyFormat, CryptoKey, CryptoKey, AlgorithmIdentifier) diff --git a/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any.worker-expected.txt index 7c32da145f2c6..14791e7765137 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any.worker-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any.worker-expected.txt @@ -49,7 +49,7 @@ PASS SubtleCrypto interface: operation verify(AlgorithmIdentifier, CryptoKey, Bu PASS SubtleCrypto interface: operation digest(AlgorithmIdentifier, BufferSource) PASS SubtleCrypto interface: operation generateKey(AlgorithmIdentifier, boolean, sequence) PASS SubtleCrypto interface: operation deriveKey(AlgorithmIdentifier, CryptoKey, AlgorithmIdentifier, boolean, sequence) -PASS SubtleCrypto interface: operation deriveBits(AlgorithmIdentifier, CryptoKey, unsigned long) +FAIL SubtleCrypto interface: operation deriveBits(AlgorithmIdentifier, CryptoKey, unsigned long) assert_equals: property has wrong .length expected 3 but got 2 PASS SubtleCrypto interface: operation importKey(KeyFormat, (BufferSource or JsonWebKey), AlgorithmIdentifier, boolean, sequence) PASS SubtleCrypto interface: operation exportKey(KeyFormat, CryptoKey) PASS SubtleCrypto interface: operation wrapKey(KeyFormat, CryptoKey, CryptoKey, AlgorithmIdentifier) diff --git a/Source/WebCore/crypto/CryptoAlgorithm.cpp b/Source/WebCore/crypto/CryptoAlgorithm.cpp index 16ba2d81f4c7b..170b2e3515957 100644 --- a/Source/WebCore/crypto/CryptoAlgorithm.cpp +++ b/Source/WebCore/crypto/CryptoAlgorithm.cpp @@ -60,7 +60,7 @@ void CryptoAlgorithm::generateKey(const CryptoAlgorithmParameters&, bool, Crypto exceptionCallback(ExceptionCode::NotSupportedError); } -void CryptoAlgorithm::deriveBits(const CryptoAlgorithmParameters&, Ref&&, size_t, VectorCallback&&, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&, WorkQueue&) +void CryptoAlgorithm::deriveBits(const CryptoAlgorithmParameters&, Ref&&, std::optional, VectorCallback&&, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&, WorkQueue&) { exceptionCallback(ExceptionCode::NotSupportedError); } diff --git a/Source/WebCore/crypto/CryptoAlgorithm.h b/Source/WebCore/crypto/CryptoAlgorithm.h index 4ece71ab002dd..d63066360f2e1 100644 --- a/Source/WebCore/crypto/CryptoAlgorithm.h +++ b/Source/WebCore/crypto/CryptoAlgorithm.h @@ -68,7 +68,7 @@ class CryptoAlgorithm : public ThreadSafeRefCounted { virtual void verify(const CryptoAlgorithmParameters&, Ref&&, Vector&& signature, Vector&&, BoolCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&); virtual void digest(Vector&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&); virtual void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&); - virtual void deriveBits(const CryptoAlgorithmParameters&, Ref&&, size_t length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&); + virtual void deriveBits(const CryptoAlgorithmParameters&, Ref&&, std::optional length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=169262 virtual void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&, UseCryptoKit); virtual void exportKey(CryptoKeyFormat, Ref&&, KeyDataCallback&&, ExceptionCallback&&, UseCryptoKit); diff --git a/Source/WebCore/crypto/SubtleCrypto.cpp b/Source/WebCore/crypto/SubtleCrypto.cpp index a389ba7d1b1dd..0a38e9e289328 100644 --- a/Source/WebCore/crypto/SubtleCrypto.cpp +++ b/Source/WebCore/crypto/SubtleCrypto.cpp @@ -936,7 +936,7 @@ void SubtleCrypto::deriveKey(JSC::JSGlobalObject& state, AlgorithmIdentifier&& a promise->reject(result.releaseException().code(), "Cannot get key length from derivedKeyType"_s); return; } - size_t length = result.releaseReturnValue(); + std::optional length = result.releaseReturnValue(); auto importAlgorithm = CryptoAlgorithmRegistry::singleton().create(importParams->identifier); auto algorithm = CryptoAlgorithmRegistry::singleton().create(params->identifier); @@ -972,7 +972,7 @@ void SubtleCrypto::deriveKey(JSC::JSGlobalObject& state, AlgorithmIdentifier&& a algorithm->deriveBits(*params, baseKey, length, WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext(), m_workQueue); } -void SubtleCrypto::deriveBits(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, CryptoKey& baseKey, unsigned length, Ref&& promise) +void SubtleCrypto::deriveBits(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, CryptoKey& baseKey, std::optional length, Ref&& promise) { auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::DeriveBits); if (paramsOrException.hasException()) { diff --git a/Source/WebCore/crypto/SubtleCrypto.h b/Source/WebCore/crypto/SubtleCrypto.h index 27bc24da77640..c76f7f1ab33ad 100644 --- a/Source/WebCore/crypto/SubtleCrypto.h +++ b/Source/WebCore/crypto/SubtleCrypto.h @@ -68,7 +68,7 @@ class SubtleCrypto : public ContextDestructionObserver, public RefCounted&&); void generateKey(JSC::JSGlobalObject&, AlgorithmIdentifier&&, bool extractable, Vector&& keyUsages, Ref&&); void deriveKey(JSC::JSGlobalObject&, AlgorithmIdentifier&&, CryptoKey& baseKey, AlgorithmIdentifier&& derivedKeyType, bool extractable, Vector&&, Ref&&); - void deriveBits(JSC::JSGlobalObject&, AlgorithmIdentifier&&, CryptoKey& baseKey, unsigned length, Ref&&); + void deriveBits(JSC::JSGlobalObject&, AlgorithmIdentifier&&, CryptoKey& baseKey, std::optional length, Ref&&); void importKey(JSC::JSGlobalObject&, KeyFormat, KeyDataVariant&&, AlgorithmIdentifier&&, bool extractable, Vector&&, Ref&&); void exportKey(KeyFormat, CryptoKey&, Ref&&); void wrapKey(JSC::JSGlobalObject&, KeyFormat, CryptoKey&, CryptoKey& wrappingKey, AlgorithmIdentifier&& wrapAlgorithm, Ref&&); diff --git a/Source/WebCore/crypto/SubtleCrypto.idl b/Source/WebCore/crypto/SubtleCrypto.idl index 923c2188131f0..8c2dc3b2d94d7 100644 --- a/Source/WebCore/crypto/SubtleCrypto.idl +++ b/Source/WebCore/crypto/SubtleCrypto.idl @@ -39,7 +39,7 @@ typedef (object or DOMString) AlgorithmIdentifier; [CallWith=CurrentGlobalObject] Promise digest(AlgorithmIdentifier algorithm, BufferSource data); [CallWith=CurrentGlobalObject] Promise generateKey(AlgorithmIdentifier algorithm, boolean extractable, sequence keyUsages); [CallWith=CurrentGlobalObject] Promise deriveKey(AlgorithmIdentifier algorithm, CryptoKey baseKey, AlgorithmIdentifier derivedKeyType, boolean extractable, sequence keyUsages); - [CallWith=CurrentGlobalObject] Promise deriveBits(AlgorithmIdentifier algorithm, CryptoKey baseKey, unsigned long length); + [CallWith=CurrentGlobalObject] Promise deriveBits(AlgorithmIdentifier algorithm, CryptoKey baseKey, optional unsigned long? length = null); [CallWith=CurrentGlobalObject] Promise importKey(KeyFormat format, (BufferSource or JsonWebKey) keyData, AlgorithmIdentifier algorithm, boolean extractable, sequence keyUsages); Promise exportKey(KeyFormat format, CryptoKey key); [CallWith=CurrentGlobalObject] Promise wrapKey(KeyFormat format, CryptoKey key, CryptoKey wrappingKey, AlgorithmIdentifier wrapAlgorithm); diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp b/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp index 7c433fc8deedf..4048e743c010e 100644 --- a/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp +++ b/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp @@ -66,7 +66,7 @@ void CryptoAlgorithmECDH::generateKey(const CryptoAlgorithmParameters& parameter callback(WTFMove(pair)); } -void CryptoAlgorithmECDH::deriveBits(const CryptoAlgorithmParameters& parameters, Ref&& baseKey, size_t length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) +void CryptoAlgorithmECDH::deriveBits(const CryptoAlgorithmParameters& parameters, Ref&& baseKey, std::optional length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) { auto& ecParameters = downcast(parameters); @@ -90,7 +90,7 @@ void CryptoAlgorithmECDH::deriveBits(const CryptoAlgorithmParameters& parameters return; } - auto unifiedCallback = [callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback)](std::optional>&& derivedKey, size_t length) mutable { + auto unifiedCallback = [callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback)](std::optional>&& derivedKey, std::optional length) mutable { if (!derivedKey) { exceptionCallback(ExceptionCode::OperationError); return; @@ -99,7 +99,7 @@ void CryptoAlgorithmECDH::deriveBits(const CryptoAlgorithmParameters& parameters callback(WTFMove(*derivedKey)); return; } - auto lengthInBytes = std::ceil(length / 8.); + auto lengthInBytes = std::ceil(*length / 8.); if (lengthInBytes > (*derivedKey).size()) { exceptionCallback(ExceptionCode::OperationError); return; diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h b/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h index ee59060b8d14c..b452fd1b5ae63 100644 --- a/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h +++ b/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h @@ -45,7 +45,7 @@ class CryptoAlgorithmECDH final : public CryptoAlgorithm { CryptoAlgorithmIdentifier identifier() const final; void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final; - void deriveBits(const CryptoAlgorithmParameters&, Ref&&, size_t length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final; + void deriveBits(const CryptoAlgorithmParameters&, Ref&&, std::optional length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final; void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&, UseCryptoKit) final; void exportKey(CryptoKeyFormat, Ref&&, KeyDataCallback&&, ExceptionCallback&&, UseCryptoKit) final; }; diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.cpp b/Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.cpp index 76ed3ee477d82..5c62a0bb0767d 100644 --- a/Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.cpp +++ b/Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.cpp @@ -44,9 +44,9 @@ CryptoAlgorithmIdentifier CryptoAlgorithmHKDF::identifier() const return s_identifier; } -void CryptoAlgorithmHKDF::deriveBits(const CryptoAlgorithmParameters& parameters, Ref&& baseKey, size_t length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) +void CryptoAlgorithmHKDF::deriveBits(const CryptoAlgorithmParameters& parameters, Ref&& baseKey, std::optional length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) { - if (!length || length % 8) { + if (!length || !(*length) || *length % 8) { exceptionCallback(ExceptionCode::OperationError); return; } @@ -54,7 +54,7 @@ void CryptoAlgorithmHKDF::deriveBits(const CryptoAlgorithmParameters& parameters UseCryptoKit useCryptoKit = context.settingsValues().cryptoKitEnabled ? UseCryptoKit::Yes : UseCryptoKit::No; dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback), [parameters = crossThreadCopy(downcast(parameters)), baseKey = WTFMove(baseKey), length, useCryptoKit] { - return platformDeriveBits(parameters, downcast(baseKey.get()), length, useCryptoKit); + return platformDeriveBits(parameters, downcast(baseKey.get()), *length, useCryptoKit); }); } diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.h b/Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.h index c38e064642b5e..ebfc4daee327f 100644 --- a/Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.h +++ b/Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.h @@ -42,7 +42,7 @@ class CryptoAlgorithmHKDF final : public CryptoAlgorithm { CryptoAlgorithmHKDF() = default; CryptoAlgorithmIdentifier identifier() const final; - void deriveBits(const CryptoAlgorithmParameters&, Ref&&, size_t length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final; + void deriveBits(const CryptoAlgorithmParameters&, Ref&&, std::optional length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final; void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&, UseCryptoKit = UseCryptoKit::No) final; ExceptionOr getKeyLength(const CryptoAlgorithmParameters&) final; diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.cpp b/Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.cpp index 3bf040f41088f..439f206ba4e91 100644 --- a/Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.cpp +++ b/Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.cpp @@ -43,16 +43,16 @@ CryptoAlgorithmIdentifier CryptoAlgorithmPBKDF2::identifier() const return s_identifier; } -void CryptoAlgorithmPBKDF2::deriveBits(const CryptoAlgorithmParameters& parameters, Ref&& baseKey, size_t length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) +void CryptoAlgorithmPBKDF2::deriveBits(const CryptoAlgorithmParameters& parameters, Ref&& baseKey, std::optional length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) { - if (!length || length % 8) { + if (!length || !(*length) || *length % 8) { exceptionCallback(ExceptionCode::OperationError); return; } dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback), [parameters = crossThreadCopy(downcast(parameters)), baseKey = WTFMove(baseKey), length] { - return platformDeriveBits(parameters, downcast(baseKey.get()), length); + return platformDeriveBits(parameters, downcast(baseKey.get()), *length); }); } diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.h b/Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.h index d526a2499f9be..4d3dfda9ab4b3 100644 --- a/Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.h +++ b/Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.h @@ -42,7 +42,7 @@ class CryptoAlgorithmPBKDF2 final : public CryptoAlgorithm { CryptoAlgorithmPBKDF2() = default; CryptoAlgorithmIdentifier identifier() const final; - void deriveBits(const CryptoAlgorithmParameters&, Ref&&, size_t length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final; + void deriveBits(const CryptoAlgorithmParameters&, Ref&&, std::optional length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final; void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&, UseCryptoKit = UseCryptoKit::No) final; ExceptionOr getKeyLength(const CryptoAlgorithmParameters&) final; diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.cpp b/Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.cpp index 15cedaf6f3098..6bcce332e2281 100644 --- a/Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.cpp +++ b/Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.cpp @@ -63,7 +63,7 @@ std::optional> CryptoAlgorithmX25519::platformDeriveBits(const C } #endif -void CryptoAlgorithmX25519::deriveBits(const CryptoAlgorithmParameters& parameters, Ref&& baseKey, size_t length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) +void CryptoAlgorithmX25519::deriveBits(const CryptoAlgorithmParameters& parameters, Ref&& baseKey, std::optional length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) { if (baseKey->type() != CryptoKey::Type::Private) { exceptionCallback(ExceptionCode::InvalidAccessError); @@ -86,7 +86,7 @@ void CryptoAlgorithmX25519::deriveBits(const CryptoAlgorithmParameters& paramete return; } - auto unifiedCallback = [callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback)](std::optional>&& derivedKey, size_t length) mutable { + auto unifiedCallback = [callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback)](std::optional>&& derivedKey, std::optional length) mutable { if (!derivedKey) { exceptionCallback(ExceptionCode::OperationError); return; @@ -95,7 +95,7 @@ void CryptoAlgorithmX25519::deriveBits(const CryptoAlgorithmParameters& paramete callback(WTFMove(*derivedKey)); return; } - auto lengthInBytes = std::ceil(length / 8.); + auto lengthInBytes = std::ceil(*length / 8.); if (lengthInBytes > (*derivedKey).size()) { exceptionCallback(ExceptionCode::OperationError); return; diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.h b/Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.h index 0a1e1efd30c45..4b66e2ae5860e 100644 --- a/Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.h +++ b/Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.h @@ -36,7 +36,7 @@ class CryptoAlgorithmX25519 final : public CryptoAlgorithm { CryptoAlgorithmIdentifier identifier() const final; void generateKey(const CryptoAlgorithmParameters& , bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& , ExceptionCallback&& , ScriptExecutionContext&); - void deriveBits(const CryptoAlgorithmParameters&, Ref&&, size_t length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final; + void deriveBits(const CryptoAlgorithmParameters&, Ref&&, std::optional length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final; void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&, UseCryptoKit) final; void exportKey(CryptoKeyFormat, Ref&&, KeyDataCallback&&, ExceptionCallback&&, UseCryptoKit) final;