|
| 1 | +const ASYMMETRIC_KEY_DETAILS_SUPPORTED = require('./asymmetricKeyDetailsSupported'); |
| 2 | +const RSA_PSS_KEY_DETAILS_SUPPORTED = require('./rsaPssKeyDetailsSupported'); |
| 3 | + |
| 4 | +const allowedAlgorithmsForKeys = { |
| 5 | + 'ec': ['ES256', 'ES384', 'ES512'], |
| 6 | + 'rsa': ['RS256', 'PS256', 'RS384', 'PS384', 'RS512', 'PS512'], |
| 7 | + 'rsa-pss': ['PS256', 'PS384', 'PS512'] |
| 8 | +}; |
| 9 | + |
| 10 | +const allowedCurves = { |
| 11 | + ES256: 'prime256v1', |
| 12 | + ES384: 'secp384r1', |
| 13 | + ES512: 'secp521r1', |
| 14 | +}; |
| 15 | + |
| 16 | +module.exports = function(algorithm, key) { |
| 17 | + if (!algorithm || !key) return; |
| 18 | + |
| 19 | + const keyType = key.asymmetricKeyType; |
| 20 | + if (!keyType) return; |
| 21 | + |
| 22 | + const allowedAlgorithms = allowedAlgorithmsForKeys[keyType]; |
| 23 | + |
| 24 | + if (!allowedAlgorithms) { |
| 25 | + throw new Error(`Unknown key type "${keyType}".`); |
| 26 | + } |
| 27 | + |
| 28 | + if (!allowedAlgorithms.includes(algorithm)) { |
| 29 | + throw new Error(`"alg" parameter for "${keyType}" key type must be one of: ${allowedAlgorithms.join(', ')}.`) |
| 30 | + } |
| 31 | + |
| 32 | + /* |
| 33 | + * Ignore the next block from test coverage because it gets executed |
| 34 | + * conditionally depending on the Node version. Not ignoring it would |
| 35 | + * prevent us from reaching the target % of coverage for versions of |
| 36 | + * Node under 15.7.0. |
| 37 | + */ |
| 38 | + /* istanbul ignore next */ |
| 39 | + if (ASYMMETRIC_KEY_DETAILS_SUPPORTED) { |
| 40 | + switch (keyType) { |
| 41 | + case 'ec': |
| 42 | + const keyCurve = key.asymmetricKeyDetails.namedCurve; |
| 43 | + const allowedCurve = allowedCurves[algorithm]; |
| 44 | + |
| 45 | + if (keyCurve !== allowedCurve) { |
| 46 | + throw new Error(`"alg" parameter "${algorithm}" requires curve "${allowedCurve}".`); |
| 47 | + } |
| 48 | + break; |
| 49 | + |
| 50 | + case 'rsa-pss': |
| 51 | + if (RSA_PSS_KEY_DETAILS_SUPPORTED) { |
| 52 | + const length = parseInt(algorithm.slice(-3), 10); |
| 53 | + const { hashAlgorithm, mgf1HashAlgorithm, saltLength } = key.asymmetricKeyDetails; |
| 54 | + |
| 55 | + if (hashAlgorithm !== `sha${length}` || mgf1HashAlgorithm !== hashAlgorithm) { |
| 56 | + throw new Error(`Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" ${algorithm}.`); |
| 57 | + } |
| 58 | + |
| 59 | + if (saltLength !== undefined && saltLength > length >> 3) { |
| 60 | + throw new Error(`Invalid key for this operation, its RSA-PSS parameter saltLength does not meet the requirements of "alg" ${algorithm}.`) |
| 61 | + } |
| 62 | + } |
| 63 | + break; |
| 64 | + } |
| 65 | + } |
| 66 | +} |
0 commit comments