Skip to content

Commit 716caf7

Browse files
committed
crypto: pass all webcrypto WPTs
1 parent c753f27 commit 716caf7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1631
-169
lines changed

lib/internal/crypto/aes.js

+5-7
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@ const {
6060
generateKey,
6161
} = require('internal/crypto/keygen');
6262

63-
const {
64-
validateInteger,
65-
validateOneOf,
66-
} = require('internal/validators');
67-
6863
const kMaxCounterLength = 128;
6964
const kTagLengths = [32, 64, 96, 104, 112, 120, 128];
7065

@@ -227,8 +222,11 @@ function aesCipher(mode, key, data, algorithm) {
227222

228223
async function aesGenerateKey(algorithm, extractable, keyUsages) {
229224
const { name, length } = algorithm;
230-
validateInteger(length, 'algorithm.length');
231-
validateOneOf(length, 'algorithm.length', kAesKeyLengths);
225+
if (!ArrayPrototypeIncludes(kAesKeyLengths, length)) {
226+
throw lazyDOMException(
227+
'AES key length must be 128, 192, or 256 bits',
228+
'OperationError');
229+
}
232230

233231
const checkUsages = ['wrapKey', 'unwrapKey'];
234232
if (name !== 'AES-KW')

lib/internal/crypto/ec.js

+14-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const {
4+
ArrayPrototypeIncludes,
45
ObjectKeys,
56
Promise,
67
SafeSet,
@@ -17,11 +18,6 @@ const {
1718
kSigEncP1363,
1819
} = internalBinding('crypto');
1920

20-
const {
21-
validateOneOf,
22-
validateString,
23-
} = require('internal/validators');
24-
2521
const {
2622
codes: {
2723
ERR_MISSING_OPTION,
@@ -88,11 +84,12 @@ function createECPublicKeyRaw(namedCurve, keyData) {
8884

8985
async function ecGenerateKey(algorithm, extractable, keyUsages) {
9086
const { name, namedCurve } = algorithm;
91-
validateString(namedCurve, 'algorithm.namedCurve');
92-
validateOneOf(
93-
namedCurve,
94-
'algorithm.namedCurve',
95-
ObjectKeys(kNamedCurveAliases));
87+
88+
if (!ArrayPrototypeIncludes(ObjectKeys(kNamedCurveAliases), namedCurve)) {
89+
throw lazyDOMException(
90+
'Unrecognized namedCurve',
91+
'NotSupportedError');
92+
}
9693

9794
const usageSet = new SafeSet(keyUsages);
9895
switch (name) {
@@ -168,11 +165,13 @@ async function ecImportKey(
168165
keyUsages) {
169166

170167
const { name, namedCurve } = algorithm;
171-
validateString(namedCurve, 'algorithm.namedCurve');
172-
validateOneOf(
173-
namedCurve,
174-
'algorithm.namedCurve',
175-
ObjectKeys(kNamedCurveAliases));
168+
169+
if (!ArrayPrototypeIncludes(ObjectKeys(kNamedCurveAliases), namedCurve)) {
170+
throw lazyDOMException(
171+
'Unrecognized namedCurve',
172+
'NotSupportedError');
173+
}
174+
176175
let keyObject;
177176
const usagesSet = new SafeSet(keyUsages);
178177
switch (format) {

lib/internal/crypto/hkdf.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ function hkdfSync(hash, key, salt, info, length) {
142142
}
143143

144144
async function hkdfDeriveBits(algorithm, baseKey, length) {
145-
validateUint32(length, 'length');
146145
const { hash } = algorithm;
147146
const salt = getArrayBufferOrView(algorithm.salt, 'algorithm.salt');
148147
const info = getArrayBufferOrView(algorithm.info, 'algorithm.info');
@@ -153,6 +152,9 @@ async function hkdfDeriveBits(algorithm, baseKey, length) {
153152
if (length !== undefined) {
154153
if (length === 0)
155154
throw lazyDOMException('length cannot be zero', 'OperationError');
155+
if (length === null)
156+
throw lazyDOMException('length cannot be null', 'OperationError');
157+
validateUint32(length, 'length');
156158
if (length % 8) {
157159
throw lazyDOMException(
158160
'length must be a multiple of 8',

lib/internal/crypto/keys.js

-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ const {
3838
ERR_ILLEGAL_CONSTRUCTOR,
3939
ERR_INVALID_ARG_TYPE,
4040
ERR_INVALID_ARG_VALUE,
41-
ERR_OUT_OF_RANGE,
4241
}
4342
} = require('internal/errors');
4443

@@ -588,8 +587,6 @@ function prepareSecretKey(key, encoding, bufferOnly = false) {
588587

589588
function createSecretKey(key, encoding) {
590589
key = prepareSecretKey(key, encoding, true);
591-
if (key.byteLength === 0)
592-
throw new ERR_OUT_OF_RANGE('key.byteLength', '> 0', key.byteLength);
593590
const handle = new KeyObjectHandle();
594591
handle.init(kKeyTypeSecret, key);
595592
return new SecretKeyObject(handle);

lib/internal/crypto/mac.js

-3
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@ async function hmacImportKey(
100100
case 'raw': {
101101
const checkLength = keyData.byteLength * 8;
102102

103-
if (checkLength === 0 || algorithm.length === 0)
104-
throw lazyDOMException('Zero-length key is not supported', 'DataError');
105-
106103
// The Web Crypto spec allows for key lengths that are not multiples of
107104
// 8. We don't. Our check here is stricter than that defined by the spec
108105
// in that we require that algorithm.length match keyData.length * 8 if

lib/internal/crypto/pbkdf2.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,16 @@ function check(password, salt, iterations, keylen, digest) {
9898
}
9999

100100
async function pbkdf2DeriveBits(algorithm, baseKey, length) {
101-
validateUint32(length, 'length');
102101
const { iterations } = algorithm;
103102
let { hash } = algorithm;
104103
const salt = getArrayBufferOrView(algorithm.salt, 'algorithm.salt');
105104
if (hash === undefined)
106105
throw new ERR_MISSING_OPTION('algorithm.hash');
107-
validateInteger(iterations, 'algorithm.iterations', 1);
106+
validateInteger(iterations, 'algorithm.iterations');
107+
if (iterations === 0)
108+
throw lazyDOMException(
109+
'iterations cannot be zero',
110+
'OperationError');
108111

109112
hash = normalizeHashName(hash.name);
110113

@@ -114,6 +117,9 @@ async function pbkdf2DeriveBits(algorithm, baseKey, length) {
114117
if (length !== undefined) {
115118
if (length === 0)
116119
throw lazyDOMException('length cannot be zero', 'OperationError');
120+
if (length === null)
121+
throw lazyDOMException('length cannot be null', 'OperationError');
122+
validateUint32(length, 'length');
117123
if (length % 8) {
118124
throw lazyDOMException(
119125
'length must be a multiple of 8',

lib/internal/crypto/util.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,11 @@ const validateByteSource = hideStackFrames((val, name) => {
278278
});
279279

280280
function onDone(resolve, reject, err, result) {
281-
if (err) return reject(err);
281+
if (err) {
282+
return reject(lazyDOMException(
283+
'The operation failed for an operation-specific reason',
284+
'OperationError'));
285+
}
282286
resolve(result);
283287
}
284288

lib/internal/crypto/webcrypto.js

-3
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,6 @@ async function importGenericSecretKey(
494494

495495
const checkLength = keyData.byteLength * 8;
496496

497-
if (checkLength === 0 || length === 0)
498-
throw lazyDOMException('Zero-length key is not supported', 'DataError');
499-
500497
// The Web Crypto spec allows for key lengths that are not multiples of
501498
// 8. We don't. Our check here is stricter than that defined by the spec
502499
// in that we require that algorithm.length match keyData.length * 8 if

src/crypto/crypto_hkdf.cc

+31-8
Original file line numberDiff line numberDiff line change
@@ -103,20 +103,43 @@ bool HKDFTraits::DeriveBits(
103103
EVPKeyCtxPointer ctx =
104104
EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr));
105105
if (!ctx || !EVP_PKEY_derive_init(ctx.get()) ||
106-
!EVP_PKEY_CTX_hkdf_mode(ctx.get(),
107-
EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) ||
108106
!EVP_PKEY_CTX_set_hkdf_md(ctx.get(), params.digest) ||
109-
!EVP_PKEY_CTX_set1_hkdf_salt(
110-
ctx.get(), params.salt.data<unsigned char>(), params.salt.size()) ||
111-
!EVP_PKEY_CTX_set1_hkdf_key(
112-
ctx.get(),
113-
reinterpret_cast<const unsigned char*>(params.key->GetSymmetricKey()),
114-
params.key->GetSymmetricKeySize()) ||
115107
!EVP_PKEY_CTX_add1_hkdf_info(
116108
ctx.get(), params.info.data<unsigned char>(), params.info.size())) {
117109
return false;
118110
}
119111

112+
if (params.key->GetSymmetricKeySize() != 0) {
113+
if (!EVP_PKEY_CTX_hkdf_mode(ctx.get(),
114+
EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) ||
115+
!EVP_PKEY_CTX_set1_hkdf_salt(
116+
ctx.get(), params.salt.data<unsigned char>(), params.salt.size()) ||
117+
!EVP_PKEY_CTX_set1_hkdf_key(ctx.get(),
118+
reinterpret_cast<const unsigned char*>(
119+
params.key->GetSymmetricKey()),
120+
params.key->GetSymmetricKeySize())) {
121+
return false;
122+
}
123+
} else {
124+
unsigned int len = EVP_MD_size(params.digest);
125+
uint8_t tempKey[len]; // NOLINT(runtime/arrays)
126+
if (params.salt.size()) {
127+
HMAC(params.digest,
128+
params.salt.data(),
129+
params.salt.size(),
130+
nullptr,
131+
0,
132+
tempKey,
133+
&len);
134+
} else {
135+
HMAC(params.digest, new char[len]{}, len, nullptr, 0, tempKey, &len);
136+
}
137+
if (!EVP_PKEY_CTX_hkdf_mode(ctx.get(), EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) ||
138+
!EVP_PKEY_CTX_set1_hkdf_key(ctx.get(), tempKey, len)) {
139+
return false;
140+
}
141+
}
142+
120143
size_t length = params.length;
121144
ByteSource::Builder buf(length);
122145
if (EVP_PKEY_derive(ctx.get(), buf.data<unsigned char>(), &length) <= 0)

src/crypto/crypto_keys.cc

-1
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,6 @@ void KeyObjectData::MemoryInfo(MemoryTracker* tracker) const {
871871
}
872872

873873
std::shared_ptr<KeyObjectData> KeyObjectData::CreateSecret(ByteSource key) {
874-
CHECK(key);
875874
return std::shared_ptr<KeyObjectData>(new KeyObjectData(std::move(key)));
876875
}
877876

test/fixtures/wpt/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Last update:
2929
- user-timing: https://github.com/web-platform-tests/wpt/tree/df24fb604e/user-timing
3030
- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/1dd414c796/wasm/jsapi
3131
- wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi
32-
- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/cdd0f03df4/WebCryptoAPI
32+
- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/edca84af42/WebCryptoAPI
3333
- webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/a370aad338/webidl/ecmascript-binding/es-exceptions
3434

3535
[Web Platform Tests]: https://github.com/web-platform-tests/wpt

0 commit comments

Comments
 (0)