crypto: fix RSA-PSS oversized salt handling · nodejs/node@ec7819d · GitHub
Skip to content

Commit ec7819d

Browse files
panvaaduh95
authored andcommitted
crypto: fix RSA-PSS oversized salt handling
Let OpenSSL handle representable salt lengths so verification of an impossible length resolves false. Guard values outside the native int32 parameter range to prevent SignJob from silently ignoring them. Move the digest-size helper next to HKDF, its remaining consumer. PR-URL: #65550 Backport-PR-URL: #66128 Assisted-by: Codex Signed-off-by: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent a4ab3d8 commit ec7819d

4 files changed

Lines changed: 49 additions & 50 deletions

File tree

‎lib/internal/crypto/hkdf.js‎

Lines changed: 16 additions & 1 deletion

‎lib/internal/crypto/rsa.js‎

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
const {
4-
MathCeil,
54
TypedArrayPrototypeGetBuffer,
65
Uint8Array,
76
} = primordials;
@@ -24,12 +23,11 @@ const {
2423
} = internalBinding('crypto');
2524

2625
const {
27-
validateInt32,
26+
isInt32,
2827
} = require('internal/validators');
2928

3029
const {
3130
bigIntArrayToUnsignedInt,
32-
getDigestSizeInBytes,
3331
getUsagesMask,
3432
jobPromise,
3533
normalizeHashName,
@@ -241,19 +239,16 @@ function rsaSignVerify(key, data, { saltLength }, signature) {
241239
throw lazyDOMException(`Key must be a ${type} key`, 'InvalidAccessError');
242240

243241
const algorithm = getCryptoKeyAlgorithm(key);
244-
if (algorithm.name === 'RSA-PSS') {
245-
try {
246-
validateInt32(
247-
saltLength,
248-
'algorithm.saltLength',
249-
0,
250-
MathCeil((algorithm.modulusLength - 1) / 8) -
251-
getDigestSizeInBytes(algorithm.hash.name) - 2);
252-
} catch (err) {
253-
throw lazyDOMException(
254-
'The operation failed for an operation-specific reason',
255-
{ name: 'OperationError', cause: err });
256-
}
242+
// RsaPssParams converts saltLength to an unsigned long, but SignJob only
243+
// accepts int32 values.
244+
if (algorithm.name === 'RSA-PSS' && !isInt32(saltLength)) {
245+
// EMSA-PSS-VERIFY treats an impossible salt length as inconsistent.
246+
if (mode === kSignJobModeVerify)
247+
return false;
248+
249+
throw lazyDOMException(
250+
'The operation failed for an operation-specific reason',
251+
'OperationError');
257252
}
258253

259254
return jobPromise(() => new SignJob(

‎lib/internal/crypto/util.js‎

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,22 +1058,6 @@ function getBlockSize(name) {
10581058
}
10591059
}
10601060

1061-
function getDigestSizeInBytes(name) {
1062-
switch (name) {
1063-
case 'SHA-1':
1064-
return 20;
1065-
case 'SHA-256': // Fall through
1066-
case 'SHA3-256':
1067-
return 32;
1068-
case 'SHA-384': // Fall through
1069-
case 'SHA3-384':
1070-
return 48;
1071-
case 'SHA-512': // Fall through
1072-
case 'SHA3-512':
1073-
return 64;
1074-
}
1075-
}
1076-
10771061
function validateKeyOps(keyOps, usagesSet) {
10781062
if (keyOps === undefined) return;
10791063
validateArray(keyOps, 'keyData.key_ops');
@@ -1145,7 +1129,6 @@ module.exports = {
11451129
bigIntArrayToUnsignedBigInt,
11461130
bigIntArrayToUnsignedInt,
11471131
getBlockSize,
1148-
getDigestSizeInBytes,
11491132
getStringOption,
11501133
getUsagesMask,
11511134
getUsagesFromMask,

‎test/parallel/test-webcrypto-sign-verify-rsa.js‎

Lines changed: 22 additions & 16 deletions

0 commit comments

Comments
 (0)