mirror of
https://github.com/hanzoai/node-jsonwebtoken.git
synced 2026-09-24 17:00:48 +00:00
* Check if node version supports asymmetricKeyDetails * Validate algorithms for ec key type * Rename variable * Rename function * Add early return for symmetric keys * Validate algorithm for RSA key type * Validate algorithm for RSA-PSS key type * Check key types for EdDSA algorithm * Rename function * Move validateKey function to module * Convert arrow to function notation * Validate key in verify function * Simplify if * Convert if to switch..case * Guard against empty key in validation * Remove empty line * Add lib to check modulus length * Add modulus length checks * Validate mgf1HashAlgorithm and saltLength * Check node version before using key details API * Use built-in modulus length getter * Fix Node version validations * Remove duplicate validateKey * Add periods to error messages * Fix validation in verify function * Make asymmetric key validation the latest validation step * Change key curve validation * Remove support for ES256K * Fix old test that was using wrong key types to sign tokens * Enable RSA-PSS for old Node versions * Add specific RSA-PSS validations on Node 16 LTS+ * Improve error message * Simplify key validation code * Fix typo * Improve error message * Change var to const in test * Change const to let to avoid reassigning problem * Improve error message * Test incorrect private key type * Rename invalid to unsupported * Test verifying of jwt token with unsupported key * Test invalid private key type * Change order of object parameters * Move validation test to separate file * Move all validation tests to separate file * Add prime256v1 ec key * Remove modulus length check * WIP: Add EC key validation tests * Fix node version checks * Fix error message check on test * Add successful tests for EC curve check * Remove only from describe * Remove `only` * Remove duplicate block of code * Move variable to a different scope and make it const * Convert allowed curves to object for faster lookup * Rename variable * Change variable assignment order * Remove unused object properties * Test RSA-PSS happy path and wrong length * Add missing tests * Pass validation if no algorithm has been provided * Test validation of invalid salt length * Test error when signing token with invalid key * Change var to const/let in verify tests * Test verifying token with invalid key * Improve test error messages * Add parameter to skip private key validation * Replace DSA key with a 4096 bit long key * Test allowInvalidPrivateKeys in key signing * Improve test message * Rename variable * Add key validation flag tests * Fix variable name in Readme * Change private to public dsa key in verify * Rename flag * Run EC validation tests conditionally * Fix tests in old node versions * Ignore block of code from test coverage * Separate EC validations tests into two different ones * Add comment * Wrap switch in if instead of having an early return * Remove unsupported algorithms from asymmetric key validation * Rename option to allowInvalidAsymmetricKeyTypes and improve Readme * 9.0.0 * adding migration notes to readme * adding changelog for version 9.0.0 Co-authored-by: julienwoll <[email protected]>
143 lines
5.3 KiB
JavaScript
143 lines
5.3 KiB
JavaScript
const validateAsymmetricKey = require('../lib/validateAsymmetricKey');
|
|
const PS_SUPPORTED = require('../lib/psSupported');
|
|
const ASYMMETRIC_KEY_DETAILS_SUPPORTED = require('../lib/asymmetricKeyDetailsSupported');
|
|
const RSA_PSS_KEY_DETAILS_SUPPORTED = require('../lib/rsaPssKeyDetailsSupported');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { createPrivateKey } = require('crypto');
|
|
const expect = require('chai').expect;
|
|
|
|
function loadKey(filename) {
|
|
return createPrivateKey(
|
|
fs.readFileSync(path.join(__dirname, filename))
|
|
);
|
|
}
|
|
|
|
const algorithmParams = {
|
|
RS256: {
|
|
invalidPrivateKey: loadKey('secp384r1-private.pem')
|
|
},
|
|
ES256: {
|
|
invalidPrivateKey: loadKey('priv.pem')
|
|
}
|
|
};
|
|
|
|
if (PS_SUPPORTED) {
|
|
algorithmParams.PS256 = {
|
|
invalidPrivateKey: loadKey('secp384r1-private.pem')
|
|
};
|
|
}
|
|
|
|
describe('Asymmetric key validation', function() {
|
|
Object.keys(algorithmParams).forEach(function(algorithm) {
|
|
describe(algorithm, function() {
|
|
const keys = algorithmParams[algorithm];
|
|
|
|
describe('when validating a key with an invalid private key type', function () {
|
|
it('should throw an error', function () {
|
|
const expectedErrorMessage = /"alg" parameter for "[\w\d-]+" key type must be one of:/;
|
|
|
|
expect(function() {
|
|
validateAsymmetricKey(algorithm, keys.invalidPrivateKey);
|
|
}).to.throw(expectedErrorMessage);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('when the function has missing parameters', function() {
|
|
it('should pass the validation if no key has been provided', function() {
|
|
const algorithm = 'ES256';
|
|
validateAsymmetricKey(algorithm);
|
|
});
|
|
|
|
it('should pass the validation if no algorithm has been provided', function() {
|
|
const key = loadKey('dsa-private.pem');
|
|
validateAsymmetricKey(null, key);
|
|
});
|
|
});
|
|
|
|
describe('when validating a key with an unsupported type', function () {
|
|
it('should throw an error', function() {
|
|
const algorithm = 'RS256';
|
|
const key = loadKey('dsa-private.pem');
|
|
const expectedErrorMessage = 'Unknown key type "dsa".';
|
|
|
|
expect(function() {
|
|
validateAsymmetricKey(algorithm, key);
|
|
}).to.throw(expectedErrorMessage);
|
|
});
|
|
});
|
|
|
|
describe('Elliptic curve algorithms', function () {
|
|
const curvesAlgorithms = [
|
|
{ algorithm: 'ES256', curve: 'prime256v1' },
|
|
{ algorithm: 'ES384', curve: 'secp384r1' },
|
|
{ algorithm: 'ES512', curve: 'secp521r1' },
|
|
];
|
|
|
|
const curvesKeys = [
|
|
{ curve: 'prime256v1', key: loadKey('prime256v1-private.pem') },
|
|
{ curve: 'secp384r1', key: loadKey('secp384r1-private.pem') },
|
|
{ curve: 'secp521r1', key: loadKey('secp521r1-private.pem') }
|
|
];
|
|
|
|
describe('when validating keys generated using Elliptic Curves', function () {
|
|
curvesAlgorithms.forEach(function(curveAlgorithm) {
|
|
curvesKeys
|
|
.forEach((curveKeys) => {
|
|
if (curveKeys.curve !== curveAlgorithm.curve) {
|
|
if (ASYMMETRIC_KEY_DETAILS_SUPPORTED) {
|
|
it(`should throw an error when validating an ${curveAlgorithm.algorithm} token for key with curve ${curveKeys.curve}`, function() {
|
|
expect(() => {
|
|
validateAsymmetricKey(curveAlgorithm.algorithm, curveKeys.key);
|
|
}).to.throw(`"alg" parameter "${curveAlgorithm.algorithm}" requires curve "${curveAlgorithm.curve}".`);
|
|
});
|
|
} else {
|
|
it(`should pass the validation for incorrect keys if the Node version does not support checking the key's curve name`, function() {
|
|
expect(() => {
|
|
validateAsymmetricKey(curveAlgorithm.algorithm, curveKeys.key);
|
|
}).not.to.throw();
|
|
});
|
|
}
|
|
} else {
|
|
it(`should accept an ${curveAlgorithm.algorithm} token for key with curve ${curveKeys.curve}`, function() {
|
|
expect(() => {
|
|
validateAsymmetricKey(curveAlgorithm.algorithm, curveKeys.key);
|
|
}).not.to.throw();
|
|
});
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
if (RSA_PSS_KEY_DETAILS_SUPPORTED) {
|
|
describe('RSA-PSS algorithms', function () {
|
|
const key = loadKey('rsa-pss-private.pem');
|
|
|
|
it(`it should throw an error when validating a key with wrong RSA-RSS parameters`, function () {
|
|
const algorithm = 'PS512';
|
|
expect(function() {
|
|
validateAsymmetricKey(algorithm, key);
|
|
}).to.throw('Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" PS512')
|
|
});
|
|
|
|
it(`it should throw an error when validating a key with invalid salt length`, function () {
|
|
const algorithm = 'PS256';
|
|
const shortSaltKey = loadKey('rsa-pss-invalid-salt-length-private.pem');
|
|
expect(function() {
|
|
validateAsymmetricKey(algorithm, shortSaltKey);
|
|
}).to.throw('Invalid key for this operation, its RSA-PSS parameter saltLength does not meet the requirements of "alg" PS256.')
|
|
});
|
|
|
|
it(`it should pass the validation when the key matches all the requirements for the algorithm`, function () {
|
|
expect(function() {
|
|
const algorithm = 'PS256';
|
|
validateAsymmetricKey(algorithm, key);
|
|
}).not.to.throw()
|
|
});
|
|
});
|
|
}
|
|
});
|