Skip to content

Feat: handle RSA-PSS generate key pair options #144

@AugustinMauroy

Description

@AugustinMauroy

Description

Since RSA-PSS generate key pair options are deprecated (DEP0154) and have reached End-of-Life status, we should provide a codemod to replace them.

  • The codemod should replace deprecated 'hash' option with 'hashAlgorithm' in RSA-PSS key generation functions.
  • The codemod should replace deprecated 'mgf1Hash' option with 'mgf1HashAlgorithm' in RSA-PSS key generation functions.
  • The codemod should handle both crypto.generateKeyPair() and crypto.generateKeyPairSync() functions.
  • The codemod should only transform options objects for RSA-PSS key type ('rsa-pss').

Additional Information

Note that the deprecated options 'hash' and 'mgf1Hash' were removed in a recent Node.js version. The options were deprecated to provide more descriptive and consistent naming. The 'hash' option should be replaced with 'hashAlgorithm' and 'mgf1Hash' should be replaced with 'mgf1HashAlgorithm'.

This deprecation only affects RSA-PSS key pair generation and does not impact other key types or crypto operations.

Examples

Case 1: crypto.generateKeyPair with hash option

Before:

const crypto = require('node:crypto');

crypto.generateKeyPair('rsa-pss', {
  modulusLength: 2048,
  hash: 'sha256',
  saltLength: 32
}, (err, publicKey, privateKey) => {
  // handle keys
});

After:

const crypto = require('node:crypto');

crypto.generateKeyPair('rsa-pss', {
  modulusLength: 2048,
  hashAlgorithm: 'sha256',
  saltLength: 32
}, (err, publicKey, privateKey) => {
  // handle keys
});

Case 2: crypto.generateKeyPairSync with mgf1Hash option

Before:

const crypto = require('node:crypto');

const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa-pss', {
  modulusLength: 2048,
  mgf1Hash: 'sha256',
  saltLength: 32
});

After:

const crypto = require('node:crypto');

const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa-pss', {
  modulusLength: 2048,
  mgf1HashAlgorithm: 'sha256',
  saltLength: 32
});

Case 3: Both deprecated options together

Before:

const crypto = require('node:crypto');

crypto.generateKeyPair('rsa-pss', {
  modulusLength: 4096,
  hash: 'sha512',
  mgf1Hash: 'sha512',
  saltLength: 64,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem'
  }
}, callback);

After:

const crypto = require('node:crypto');

crypto.generateKeyPair('rsa-pss', {
  modulusLength: 4096,
  hashAlgorithm: 'sha512',
  mgf1HashAlgorithm: 'sha512',
  saltLength: 64,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem'
  }
}, callback);

Case 4: ESM import with generateKeyPairSync

Before:

import { generateKeyPairSync } from 'node:crypto';

const keys = generateKeyPairSync('rsa-pss', {
  modulusLength: 2048,
  hash: 'sha384',
  mgf1Hash: 'sha384'
});

After:

import { generateKeyPairSync } from 'node:crypto';

const keys = generateKeyPairSync('rsa-pss', {
  modulusLength: 2048,
  hashAlgorithm: 'sha384',
  mgf1HashAlgorithm: 'sha384'
});

Case 5: Variable options object

Before:

const crypto = require('node:crypto');

const options = {
  modulusLength: 2048,
  hash: 'sha256',
  mgf1Hash: 'sha1',
  saltLength: 20
};

crypto.generateKeyPair('rsa-pss', options, (err, publicKey, privateKey) => {
  // handle keys
});

After:

const crypto = require('node:crypto');

const options = {
  modulusLength: 2048,
  hashAlgorithm: 'sha256',
  mgf1HashAlgorithm: 'sha1',
  saltLength: 20
};

crypto.generateKeyPair('rsa-pss', options, (err, publicKey, privateKey) => {
  // handle keys
});

Case 6: Namespace import

Before:

import * as crypto from 'node:crypto';

crypto.generateKeyPair('rsa-pss', {
  modulusLength: 3072,
  hash: 'sha256'
}, callback);

After:

import * as crypto from 'node:crypto';

crypto.generateKeyPair('rsa-pss', {
  modulusLength: 3072,
  hashAlgorithm: 'sha256'
}, callback);

Case 7: Promise-based usage

Before:

const { promisify } = require('node:util');
const crypto = require('node:crypto');

const generateKeyPairAsync = promisify(crypto.generateKeyPair);

generateKeyPairAsync('rsa-pss', {
  modulusLength: 2048,
  hash: 'sha256',
  mgf1Hash: 'sha256'
}).then(({ publicKey, privateKey }) => {
  // handle keys
});

After:

const { promisify } = require('node:util');
const crypto = require('node:crypto');

const generateKeyPairAsync = promisify(crypto.generateKeyPair);

generateKeyPairAsync('rsa-pss', {
  modulusLength: 2048,
  hashAlgorithm: 'sha256',
  mgf1HashAlgorithm: 'sha256'
}).then(({ publicKey, privateKey }) => {
  // handle keys
});

Case 8: Only hash option present

Before:

const crypto = require('node:crypto');

const keyPair = crypto.generateKeyPairSync('rsa-pss', {
  modulusLength: 2048,
  hash: 'sha512'
});

After:

const crypto = require('node:crypto');

const keyPair = crypto.generateKeyPairSync('rsa-pss', {
  modulusLength: 2048,
  hashAlgorithm: 'sha512'
});

Case 9: Only mgf1Hash option present

Before:

const crypto = require('node:crypto');

crypto.generateKeyPair('rsa-pss', {
  modulusLength: 4096,
  mgf1Hash: 'sha384',
  saltLength: 48
}, (err, publicKey, privateKey) => {
  if (err) throw err;
  // use keys
});

After:

const crypto = require('node:crypto');

crypto.generateKeyPair('rsa-pss', {
  modulusLength: 4096,
  mgf1HashAlgorithm: 'sha384',
  saltLength: 48
}, (err, publicKey, privateKey) => {
  if (err) throw err;
  // use keys
});

Case 10: Should not affect other key types

Before:

const crypto = require('node:crypto');

// This should NOT be transformed (not rsa-pss)
crypto.generateKeyPair('rsa', {
  modulusLength: 2048,
  hash: 'sha256'  // This is not the deprecated option for regular RSA
}, callback);

// This SHOULD be transformed (rsa-pss)
crypto.generateKeyPair('rsa-pss', {
  modulusLength: 2048,
  hash: 'sha256'
}, callback);

After:

const crypto = require('node:crypto');

// This should NOT be transformed (not rsa-pss)
crypto.generateKeyPair('rsa', {
  modulusLength: 2048,
  hash: 'sha256'  // This is not the deprecated option for regular RSA
}, callback);

// This SHOULD be transformed (rsa-pss)
crypto.generateKeyPair('rsa-pss', {
  modulusLength: 2048,
  hashAlgorithm: 'sha256'
}, callback);

Refs

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    🏗 In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions