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

Commit 9941fb5

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. Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: #65550 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent c721aab commit 9941fb5

4 files changed

Lines changed: 47 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
@@ -1070,22 +1070,6 @@ function getBlockSize(name) {
10701070
}
10711071
}
10721072

1073-
function getDigestSizeInBytes(name) {
1074-
switch (name) {
1075-
case 'SHA-1':
1076-
return 20;
1077-
case 'SHA-256': // Fall through
1078-
case 'SHA3-256':
1079-
return 32;
1080-
case 'SHA-384': // Fall through
1081-
case 'SHA3-384':
1082-
return 48;
1083-
case 'SHA-512': // Fall through
1084-
case 'SHA3-512':
1085-
return 64;
1086-
}
1087-
}
1088-
10891073
function validateKeyOps(keyOps, usagesSet) {
10901074
if (keyOps === undefined) return;
10911075
validateArray(keyOps, 'keyData.key_ops');
@@ -1159,7 +1143,6 @@ module.exports = {
11591143
bigIntArrayToUnsignedBigInt,
11601144
bigIntArrayToUnsignedInt,
11611145
getBlockSize,
1162-
getDigestSizeInBytes,
11631146
getStringOption,
11641147
getUsagesMask,
11651148
getUsagesFromMask,

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

Lines changed: 20 additions & 16 deletions

0 commit comments

Comments
 (0)