UNPKG

crypto-key-composer

Version:

A library to decompose and compose crypto keys of different types and formats

164 lines (131 loc) 4.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.maybeEncryptPemBody = exports.maybeDecryptPemBody = void 0; var _pbe = require("../../util/pbe"); var _binary = require("../../util/binary"); var _validator = require("../../util/validator"); var _errors = require("../../util/errors"); const decryptPemBody = (pem, password) => { const keyDerivationFunc = { id: 'openssl-derive-bytes' }; const encryptionScheme = { iv: (0, _binary.hexStringToUint8Array)(pem.dekInfo.parameters) }; const dekInfoAlgorithm = pem.dekInfo.algorithm; switch (dekInfoAlgorithm) { case 'AES-128-CBC': case 'AES-192-CBC': case 'AES-256-CBC': encryptionScheme.id = dekInfoAlgorithm.replace('-', '').toLowerCase(); break; case 'RC2-40-CBC': case 'RC2-64-CBC': case 'RC2-128-CBC': case 'RC2-CBC': encryptionScheme.id = 'rc2-cbc'; encryptionScheme.bits = Number((dekInfoAlgorithm.match(/-(\d+)-/) || [])[1]) || 128; break; case 'DES-CBC': case 'DES-EDE3-CBC': encryptionScheme.id = dekInfoAlgorithm.toLowerCase(); break; default: throw new _errors.UnsupportedAlgorithmError(`Unsupported DEK-INFO algorithm '${dekInfoAlgorithm}'`); } const encryptionAlgorithm = { keyDerivationFunc, encryptionScheme }; const decryptedPemBody = (0, _pbe.decryptWithPassword)((0, _binary.binaryStringToUint8Array)(pem.body), encryptionAlgorithm, password); return { encryptionAlgorithm, pemBody: decryptedPemBody }; }; const encryptPemBody = (pemBody, encryptionAlgorithm, password) => { encryptionAlgorithm = (0, _validator.validateEncryptionAlgorithm)(encryptionAlgorithm, 'openssl-derive-bytes', 'aes256-cbc'); const { keyDerivationFunc, encryptionScheme } = encryptionAlgorithm; if (keyDerivationFunc.id !== 'openssl-derive-bytes') { throw new _errors.UnsupportedAlgorithmError('PKCS1 PEM keys only support \'openssl-derive-bytes\' as the key derivation func'); } let dekInfoAlgorithm; switch (encryptionScheme.id) { case 'aes128-cbc': case 'aes192-cbc': case 'aes256-cbc': dekInfoAlgorithm = encryptionScheme.id.replace('aes', 'aes-').toUpperCase(); break; case 'rc2-cbc': encryptionScheme.bits = encryptionScheme.bits || 128; switch (encryptionScheme.bits) { case 40: dekInfoAlgorithm = 'RC2-40-CBC'; break; case 64: dekInfoAlgorithm = 'RC2-64-CBC'; break; case 128: dekInfoAlgorithm = 'RC2-CBC'; break; default: throw new _errors.UnsupportedAlgorithmError(`Unsupported RC2 bits parameter with value '${encryptionScheme.bits}'`); } break; case 'des-cbc': case 'des-ede3-cbc': dekInfoAlgorithm = encryptionScheme.id.toUpperCase(); break; default: throw new _errors.UnsupportedAlgorithmError(`Unsupported encryption scheme id '${encryptionScheme.id}'`); } const { encryptedData, effectiveEncryptionAlgorithm } = (0, _pbe.encryptWithPassword)(pemBody, encryptionAlgorithm, password); return { pemHeaders: { procType: { version: '4', type: 'ENCRYPTED' }, dekInfo: { algorithm: dekInfoAlgorithm, parameters: (0, _binary.uint8ArrayToHexString)(effectiveEncryptionAlgorithm.encryptionScheme.iv).toUpperCase() } }, pemBody: encryptedData }; }; const maybeDecryptPemBody = (pem, password) => { const encrypted = pem.procType && pem.procType.type === 'ENCRYPTED' && pem.dekInfo && pem.dekInfo.algorithm; if (!encrypted) { return { pemBody: (0, _binary.binaryStringToUint8Array)(pem.body), encryptionAlgorithm: null }; } if (!password) { throw new _errors.MissingPasswordError('Please specify the password to decrypt the key'); } return decryptPemBody(pem, password); }; exports.maybeDecryptPemBody = maybeDecryptPemBody; const maybeEncryptPemBody = (pemBody, encryptionAlgorithm, password) => { if (!password && !encryptionAlgorithm) { return { pemHeaders: null, pemBody }; } if (!password && encryptionAlgorithm) { throw new _errors.MissingPasswordError('An encryption algorithm was specified but no password was set'); } return encryptPemBody(pemBody, encryptionAlgorithm, password); }; exports.maybeEncryptPemBody = maybeEncryptPemBody;