diff --git a/lib/config/__fixtures__/private.pem b/lib/config/__fixtures__/private.pem deleted file mode 100644 index efee57e904..0000000000 --- a/lib/config/__fixtures__/private.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEAzVLc1KmhWxcLnoPTPpQwxVHySFx4vY+0Sk+2AdnlJvrTFlNR -8XgBPdgU9SDwHFFTYyXRQ/msm0YMOBRoIdz4/psz6IzRV80aOtDIkUPAU+cdqnje -3rusrPnqCykDuIHGoBZ8zlt57t/8OVNOduUflrQRqMFors8iLWcNjuGJfZAusI5B -M8KYYDPL2oUo/8AV0bWN8MdNnxDSwGtan4bbzrtG6dpNzyntsG5DkL1h8OZRki4S -kHf+71ZzJFz1KcyrzBVJ9DBxdiJdmLLkv9caLLc2QS0VFmtfLnlrga3Sahy6YNwc -rN33aaNOXwFPSErsKWIgIf16eOaSUQCFusXY9QIDAQABAoIBAQCkltMM6nm9Ikkf -JX9V/8bkth7o4K+tDSAyHZnB/CBUUeaaU+oxDci5AZkzMtcnbA3TQcJxohg6VDmB -TuJ2msNCnblLpm492t023pyYzd3DpFXEjKXjmEAAXUm+7n7cDbPiKoSbivrAgO6Y -KW6RonPjA6/QPlIjJ0m3aY+VxLfJXTYVfFBk+0HGEAvmrSSSEezXej8Qzs9CRKtz -cQkR5Bs749SS509MHxaslP7n366EvJBJkqrjUxA6kbxOxUkuuOWF9jfduDAG+NYc -pe4IXFOYMpK/w29wqvkNulKYs+FHXr1sGjkztGjyNnjP0NnX+r0EYU07xLJ26krD -KMWQG8sBAoGBAO93iFrPnEBnnKojI8b+u3YowVCz0HVuHHIStHd9uUgfsn/Bxfls -HRIlg8l1MJd69TT0knOhkJxBCP+b/qBvid7YLbTxIVELCAfLAzsmGgY+DEN/TTUb -FDvHGa/drCnkSR/O/RbtHvMQISzTja1siYrdwwY+wpwzR2tB7ZH/9iO1AoGBANt/ -3Srpv4BbP7JZ+cNte4JfI2gZq41mo+DF5ryuFZzsP3R5SZ1BOapQGyLEATQaoxsJ -QZsI73KPBzab0/+E75qJuXckIGmFftHXgoQpClGvPaEDF9M21QW5Y3vKVa/45qhy -3wpb8gEYqrt1x0rmzyumCtCD8J470Er64gE1eKhBAoGBALW6ScFYwqRhvROkvTb8 -A7mE7kfXXgBwAqhTJ59yytRAMc8gd6R0do9Z5uxQwgKDLmj0ndugpcTe2fxZHuAU -JVX3SqCBSZ5eN8bqOtZ9cMyB8/6ZMjd2CGHhE85R9KCJ/TBlfc4TPySIfhStq1wL -/UlkR+eKY1f01mNAUhE1ZU7tAoGBAKwS/B51KsSERFYcRToYbRfSX55vaVarnVNL -scw+qQDhEAnOP5CBHqTOscc6YzsmmrFKO10/zv8+80ezN6n73B6JU5T8BFDU74uv -6EiVJ9rLh4PfOeFB/hPDtyLHhw8yEBkEHKgxVnHXlZjqBzdH5Cdyvs2icZKKj4sI -TP7nnVRBAoGAPZBjjTn9HgB9et5Kdovp+7nr842WboxwklVyTpbNGAjIxNXIXex+ -TST21UbquTIpIrpYRk1WMIu9T5PndAagDWVEsmUYQZeuhmuY64K+iviRsfdGthws -nbbR8sMEkn4XEtPZfrEBq27g01RNmIIMW5Es2O5N2AjLlyeBOh099Fw= ------END RSA PRIVATE KEY----- diff --git a/lib/config/decrypt.ts b/lib/config/decrypt.ts index 5920c0e879..729e7015e4 100644 --- a/lib/config/decrypt.ts +++ b/lib/config/decrypt.ts @@ -6,10 +6,6 @@ import { regEx } from '../util/regex'; import { addSecretForSanitizing } from '../util/sanitize'; import { ensureTrailingSlash, parseUrl, trimSlashes } from '../util/url'; import { tryDecryptKbPgp } from './decrypt/kbpgp'; -import { - tryDecryptPublicKeyDefault, - tryDecryptPublicKeyPKCS1, -} from './decrypt/legacy'; import { tryDecryptOpenPgp } from './decrypt/openpgp'; import { GlobalConfig } from './global'; import { DecryptedObject } from './schema'; @@ -30,35 +26,14 @@ export async function tryDecrypt( key: string, encryptedStr: string, repository: string, - keyName: string, ): Promise { let decryptedStr: string | null = null; - if (key?.startsWith('-----BEGIN PGP PRIVATE KEY BLOCK-----')) { - const decryptedObjStr = - getEnv().RENOVATE_X_USE_OPENPGP === 'true' - ? await tryDecryptOpenPgp(key, encryptedStr) - : await tryDecryptKbPgp(key, encryptedStr); - if (decryptedObjStr) { - decryptedStr = validateDecryptedValue(decryptedObjStr, repository); - } - } else { - decryptedStr = tryDecryptPublicKeyDefault(key, encryptedStr); - if (is.string(decryptedStr)) { - logger.warn( - { keyName }, - 'Encrypted value is using deprecated default padding, please change to using PGP encryption.', - ); - } else { - decryptedStr = tryDecryptPublicKeyPKCS1(key, encryptedStr); - /* v8 ignore start -- not testable */ - if (is.string(decryptedStr)) { - logger.warn( - { keyName }, - 'Encrypted value is using deprecated PKCS1 padding, please change to using PGP encryption.', - ); - } - /* v8 ignore stop */ - } + const decryptedObjStr = + getEnv().RENOVATE_X_USE_OPENPGP === 'true' + ? await tryDecryptOpenPgp(key, encryptedStr) + : await tryDecryptKbPgp(key, encryptedStr); + if (decryptedObjStr) { + decryptedStr = validateDecryptedValue(decryptedObjStr, repository); } return decryptedStr; } @@ -170,20 +145,10 @@ export async function decryptConfig( if (privateKey) { for (const [eKey, eVal] of Object.entries(val)) { logger.debug(`Trying to decrypt ${eKey} in ${path}`); - let decryptedStr = await tryDecrypt( - privateKey, - eVal, - repository, - eKey, - ); + let decryptedStr = await tryDecrypt(privateKey, eVal, repository); if (privateKeyOld && !is.nonEmptyString(decryptedStr)) { logger.debug(`Trying to decrypt with old private key`); - decryptedStr = await tryDecrypt( - privateKeyOld, - eVal, - repository, - eKey, - ); + decryptedStr = await tryDecrypt(privateKeyOld, eVal, repository); } if (!is.nonEmptyString(decryptedStr)) { const error = new Error('config-validation'); diff --git a/lib/config/decrypt/legacy.spec.ts b/lib/config/decrypt/legacy.spec.ts deleted file mode 100644 index c28b80ca6f..0000000000 --- a/lib/config/decrypt/legacy.spec.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { CONFIG_VALIDATION } from '../../constants/error-messages'; -import { decryptConfig, setPrivateKeys } from '../decrypt'; -import { GlobalConfig } from '../global'; -import type { RenovateConfig } from '../types'; -import { Fixtures } from '~test/fixtures'; - -const privateKey = Fixtures.get('private.pem', '..'); -const repository = 'abc/def'; - -describe('config/decrypt/legacy', () => { - describe('decryptConfig()', () => { - let config: RenovateConfig; - - beforeEach(() => { - config = {}; - GlobalConfig.reset(); - setPrivateKeys(undefined, undefined); - }); - - it('handles invalid encrypted type', async () => { - config.encrypted = 1; - setPrivateKeys(privateKey, undefined); - const res = await decryptConfig(config, repository); - expect(res.encrypted).toBeUndefined(); - }); - - it('handles invalid encrypted value', async () => { - config.encrypted = { a: 1 }; - setPrivateKeys(privateKey, 'invalid-key'); - await expect(decryptConfig(config, repository)).rejects.toThrow( - CONFIG_VALIDATION, - ); - }); - - it('replaces npm token placeholder in npmrc', async () => { - setPrivateKeys('invalid-key', privateKey); // test old key failover - config.npmrc = - '//registry.npmjs.org/:_authToken=${NPM_TOKEN}\n//registry.npmjs.org/:_authToken=${NPM_TOKEN}\n'; - config.encrypted = { - npmToken: - 'FLA9YHIzpE7YetAg/P0X46npGRCMqn7hgyzwX5ZQ9wYgu9BRRbTiBVsUIFTyM5BuP1Q22slT2GkWvFvum7GU236Y6QiT7Nr8SLvtsJn2XUuq8H7REFKzdy3+wqyyWbCErYTFyY1dcPM7Ht+CaGDWdd8u/FsoX7AdMRs/X1jNUo6iSmlUiyGlYDKF+QMnCJom1VPVgZXWsGKdjI2MLny991QMaiv0VajmFIh4ENv4CtXOl/1twvIl/6XTXAaqpJJKDTPZEuydi+PHDZmal2RAOfrkH4m0UURa7SlfpUlIg+EaqbNGp85hCYXLwRcEET1OnYr3rH1oYkcYJ40any1tvQ==', - }; - const res = await decryptConfig(config, repository); - expect(res.encrypted).toBeUndefined(); - expect(res.npmToken).toBe('abcdef-ghijklm-nopqf-stuvwxyz'); - }); - - it('appends npm token in npmrc', async () => { - setPrivateKeys(privateKey, undefined); - config.npmrc = 'foo=bar\n'; - config.encrypted = { - npmToken: - 'FLA9YHIzpE7YetAg/P0X46npGRCMqn7hgyzwX5ZQ9wYgu9BRRbTiBVsUIFTyM5BuP1Q22slT2GkWvFvum7GU236Y6QiT7Nr8SLvtsJn2XUuq8H7REFKzdy3+wqyyWbCErYTFyY1dcPM7Ht+CaGDWdd8u/FsoX7AdMRs/X1jNUo6iSmlUiyGlYDKF+QMnCJom1VPVgZXWsGKdjI2MLny991QMaiv0VajmFIh4ENv4CtXOl/1twvIl/6XTXAaqpJJKDTPZEuydi+PHDZmal2RAOfrkH4m0UURa7SlfpUlIg+EaqbNGp85hCYXLwRcEET1OnYr3rH1oYkcYJ40any1tvQ==', - }; - const res = await decryptConfig(config, repository); - expect(res.encrypted).toBeUndefined(); - expect(res.npmToken).toBe('abcdef-ghijklm-nopqf-stuvwxyz'); - }); - - it('decrypts nested', async () => { - setPrivateKeys(privateKey, undefined); - config.packageFiles = [ - { - packageFile: 'package.json', - devDependencies: { - encrypted: { - branchPrefix: - 'FLA9YHIzpE7YetAg/P0X46npGRCMqn7hgyzwX5ZQ9wYgu9BRRbTiBVsUIFTyM5BuP1Q22slT2GkWvFvum7GU236Y6QiT7Nr8SLvtsJn2XUuq8H7REFKzdy3+wqyyWbCErYTFyY1dcPM7Ht+CaGDWdd8u/FsoX7AdMRs/X1jNUo6iSmlUiyGlYDKF+QMnCJom1VPVgZXWsGKdjI2MLny991QMaiv0VajmFIh4ENv4CtXOl/1twvIl/6XTXAaqpJJKDTPZEuydi+PHDZmal2RAOfrkH4m0UURa7SlfpUlIg+EaqbNGp85hCYXLwRcEET1OnYr3rH1oYkcYJ40any1tvQ==', - npmToken: - 'FLA9YHIzpE7YetAg/P0X46npGRCMqn7hgyzwX5ZQ9wYgu9BRRbTiBVsUIFTyM5BuP1Q22slT2GkWvFvum7GU236Y6QiT7Nr8SLvtsJn2XUuq8H7REFKzdy3+wqyyWbCErYTFyY1dcPM7Ht+CaGDWdd8u/FsoX7AdMRs/X1jNUo6iSmlUiyGlYDKF+QMnCJom1VPVgZXWsGKdjI2MLny991QMaiv0VajmFIh4ENv4CtXOl/1twvIl/6XTXAaqpJJKDTPZEuydi+PHDZmal2RAOfrkH4m0UURa7SlfpUlIg+EaqbNGp85hCYXLwRcEET1OnYr3rH1oYkcYJ40any1tvQ==', - }, - }, - }, - 'backend/package.json', - ]; - // TODO: fix types #22198 - const res = (await decryptConfig(config, repository)) as any; - expect(res.encrypted).toBeUndefined(); - expect(res.packageFiles[0].devDependencies.encrypted).toBeUndefined(); - expect(res.packageFiles[0].devDependencies.branchPrefix).toBe( - 'abcdef-ghijklm-nopqf-stuvwxyz', - ); - expect(res.packageFiles[0].devDependencies.npmToken).toBe( - 'abcdef-ghijklm-nopqf-stuvwxyz', - ); - }); - }); -}); diff --git a/lib/config/decrypt/legacy.ts b/lib/config/decrypt/legacy.ts deleted file mode 100644 index c220bb3ca9..0000000000 --- a/lib/config/decrypt/legacy.ts +++ /dev/null @@ -1,39 +0,0 @@ -import crypto from 'node:crypto'; -import { logger } from '../../logger'; - -export function tryDecryptPublicKeyPKCS1( - privateKey: string, - encryptedStr: string, -): string | null { - let decryptedStr: string | null = null; - try { - decryptedStr = crypto - .privateDecrypt( - { - key: privateKey, - padding: crypto.constants.RSA_PKCS1_PADDING, - }, - Buffer.from(encryptedStr, 'base64'), - ) - .toString(); - } catch { - logger.debug('Could not decrypt using PKCS1 padding'); - } - return decryptedStr; -} - -export function tryDecryptPublicKeyDefault( - privateKey: string, - encryptedStr: string, -): string | null { - let decryptedStr: string | null = null; - try { - decryptedStr = crypto - .privateDecrypt(privateKey, Buffer.from(encryptedStr, 'base64')) - .toString(); - logger.debug('Decrypted config using default padding'); - } catch { - logger.debug('Could not decrypt using default padding'); - } - return decryptedStr; -}