Skip to content

Commit c172469

Browse files
committed
chore: wip
1 parent 71aa386 commit c172469

1 file changed

Lines changed: 39 additions & 29 deletions

File tree

src/pbe.ts

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import type { PemMessage, PemHeader, Pem } from './pem'
2525
import { aes } from './aes'
2626
import { asn1 } from './asn1'
2727
import { wrapRsaPrivateKey, privateKeyToAsn1, privateKeyFromAsn1 } from './rsa'
28-
import { createCipher as createCipherOriginal } from './cipher'
28+
import { createCipher, createCipher as createCipherOriginal, createDecipher } from './cipher'
2929
import { sha1 } from './sha1'
3030
import { des } from './des'
3131
import { oids } from './oids'
@@ -755,7 +755,8 @@ export function encryptPrivateKeyInfo(obj: any, password: string, options: Encry
755755
if (!cipherFn) throw new Error('Cipher function is not defined')
756756
const iv = createBuffer(getBytesSync(ivLen))
757757
const cipher = cipherFn(toByteStringBuffer(dk))
758-
cipher.start({ iv: createBuffer(iv) })
758+
if (!iv) throw new Error('IV is required')
759+
cipher.start({ iv: convertToString(iv) })
759760
cipher.update(asn1.toDer(obj))
760761
if (!cipher.finish())
761762
throw new Error('Failed to finish encryption')
@@ -801,9 +802,9 @@ export function encryptPrivateKeyInfo(obj: any, password: string, options: Encry
801802
dkLen = 24
802803

803804
const saltBytes = new ByteStringBuff(salt)
804-
const dk = generatePkcs12Key(password, saltBytes.bytes(), 1, count, dkLen)
805-
const iv = generatePkcs12Key(password, saltBytes.bytes(), 2, count, dkLen)
806-
const cipher = des.createEncryptionCipher(dk, iv)
805+
const dk = generatePkcs12Key(password, createBuffer(saltBytes.bytes()), 1, count, dkLen)
806+
const iv = generatePkcs12Key(password, createBuffer(saltBytes.bytes()), 2, count, dkLen)
807+
const cipher = des.createEncryptionCipher(convertToString(dk), convertToString(iv))
807808

808809
cipher.update(asn1.toDer(obj))
809810
cipher.finish()
@@ -858,7 +859,7 @@ export function decryptPrivateKeyInfo(obj: any, password: string): any {
858859
let rval = null
859860

860861
// get PBE params
861-
const capture: { kdfOid?: string; encOid?: string; kdfSalt?: string; kdfIterationCount?: string; encIv?: string; encryptionOid?: string; encryptionParams?: any; encryptedData?: string; } = {}
862+
const capture: CaptureObject = {}
862863
const errors: Error[] = []
863864

864865
if (!asn1.validate(obj, encryptedPrivateKeyValidator, capture, errors)) {
@@ -965,40 +966,40 @@ export function encryptRsaPrivateKey(rsaKey: any, password: string, options: Enc
965966

966967
// Legacy implementation...
967968
let algorithm: string
968-
let iv: ByteStringBuffer
969+
let initialIv: ByteStringBuffer
969970
let dkLen: number
970971
let cipherFn: CipherCreator
971972

972973
switch (options.algorithm) {
973974
case 'aes128':
974975
algorithm = 'AES-128-CBC'
975976
dkLen = 16
976-
iv = createBuffer(getBytesSync(16))
977+
initialIv = createBuffer(getBytesSync(16))
977978
cipherFn = (key) => aes.createEncryptionCipher(convertToString(key), '128')
978979
break
979980
case 'aes192':
980981
algorithm = 'AES-192-CBC'
981982
dkLen = 24
982-
iv = createBuffer(getBytesSync(16))
983+
initialIv = createBuffer(getBytesSync(16))
983984
cipherFn = (key) => aes.createEncryptionCipher(convertToString(key), '192')
984985
break
985986
case 'aes256':
986987
algorithm = 'AES-256-CBC'
987988
dkLen = 32
988-
iv = createBuffer(getBytesSync(16))
989+
initialIv = createBuffer(getBytesSync(16))
989990
cipherFn = (key) => aes.createEncryptionCipher(convertToString(key), '256')
990991
break
991992
case '3des':
992993
algorithm = 'DES-EDE3-CBC'
993994
dkLen = 24
994-
iv = createBuffer(getBytesSync(8))
995-
cipherFn = (key) => des.createEncryptionCipher(convertToString(key), iv.bytes())
995+
initialIv = createBuffer(getBytesSync(8))
996+
cipherFn = (key) => des.createEncryptionCipher(convertToString(key), initialIv.bytes())
996997
break
997998
case 'des':
998999
algorithm = 'DES-CBC'
9991000
dkLen = 8
1000-
iv = createBuffer(getBytesSync(8))
1001-
cipherFn = (key) => des.createEncryptionCipher(convertToString(key), iv.bytes())
1001+
initialIv = createBuffer(getBytesSync(8))
1002+
cipherFn = (key) => des.createEncryptionCipher(convertToString(key), initialIv.bytes())
10021003
break
10031004
default:
10041005
const error: CustomError = new Error(
@@ -1008,10 +1009,11 @@ export function encryptRsaPrivateKey(rsaKey: any, password: string, options: Enc
10081009
throw error
10091010
}
10101011

1011-
const dk = opensslDeriveBytes(password, iv.bytes(), dkLen, sha1.create())
1012-
const iv = createBuffer(getBytesSync(16))
1012+
const dk = opensslDeriveBytes(password, initialIv.bytes(), dkLen, sha1.create())
1013+
const finalIv = createBuffer(getBytesSync(16))
10131014
const cipher = cipherFn(createBuffer(dk))
1014-
cipher.start({ iv })
1015+
if (!finalIv) throw new Error('IV is required')
1016+
cipher.start({ iv: convertToString(finalIv) })
10151017
cipher.update(asn1.toDer(privateKeyToAsn1(rsaKey)))
10161018
if (!cipher.finish()) {
10171019
throw new Error('Failed to finish encryption')
@@ -1028,7 +1030,7 @@ export function encryptRsaPrivateKey(rsaKey: any, password: string, options: Enc
10281030
},
10291031
dekInfo: {
10301032
algorithm,
1031-
parameters: bytesToHex(iv.bytes()).toUpperCase()
1033+
parameters: bytesToHex(finalIv.bytes()).toUpperCase()
10321034
},
10331035
headers: [],
10341036
body: cipher.output.getBytes(),
@@ -1074,11 +1076,12 @@ export function decryptRsaPrivateKey(pemKey: string, password: string): any {
10741076
prf: DEFAULT_ENCRYPTION_PARAMS.prfAlgorithm
10751077
})
10761078

1077-
validateKey(key, pbeAlgorithms[params.algorithm].keyLength)
1078-
validateIV(params.iv, pbeAlgorithms[params.algorithm].ivLength)
1079+
const algorithm = params.algorithm || 'aes128-CBC'
1080+
validateKey(key, pbeAlgorithms[algorithm].keyLength)
1081+
validateIV(params.iv, pbeAlgorithms[algorithm].ivLength)
10791082

10801083
const decipher = createModernCipher(
1081-
pbeAlgorithms[params.algorithm].cipher,
1084+
pbeAlgorithms[algorithm].cipher,
10821085
key
10831086
)
10841087

@@ -1237,7 +1240,8 @@ export function getCipherForPBES2(oid: string, params: any, password: string): B
12371240
if (!cipherFn) throw new Error('Cipher function is not defined')
12381241
const iv = capture.encIv
12391242
const cipher = cipherFn(convertToString(dk))
1240-
cipher.start({ iv: createBuffer(iv) })
1243+
if (!iv) throw new Error('IV is required')
1244+
cipher.start({ iv: convertToString(iv) })
12411245

12421246
return cipher
12431247
}
@@ -1265,42 +1269,47 @@ export function getCipherForPKCS12PBE(oid: string, params: Asn1Object, password:
12651269
throw error
12661270
}
12671271

1268-
const salt = createBuffer(capture.salt)
1269-
const countBuffer = createBuffer(capture.iterations)
1272+
const validatedCapture = capture as CaptureObject
1273+
const salt = createBuffer(validatedCapture.salt)
1274+
const countBuffer = createBuffer(validatedCapture.iterations)
12701275
const iterationCount = countBuffer.getInt(countBuffer.length() << 3)
12711276

12721277
let dkLen, dIvLen, cipherFn
12731278
switch (oid) {
12741279
case oids['pbeWithSHAAnd3-KeyTripleDES-CBC']:
12751280
dkLen = 24
12761281
dIvLen = 8
1277-
cipherFn = des.startDecrypting
1282+
cipherFn = function (key: string, iv: string) {
1283+
const cipher = createCipher('3DES-CBC', key)
1284+
cipher.start({ iv })
1285+
return cipher
1286+
}
12781287
break
12791288

12801289
case oids['pbewithSHAAnd40BitRC2-CBC']:
12811290
dkLen = 5
12821291
dIvLen = 8
12831292
cipherFn = function (key: string, iv: string) {
12841293
const cipher = rc2.createDecryptionCipher(key, 40)
1285-
cipher.start(iv, null)
1294+
cipher.start({ iv })
12861295
return cipher
12871296
}
12881297
break
12891298

12901299
default:
1291-
var error = new Error('Cannot read PKCS #12 PBE data block. Unsupported OID.')
1300+
const error: CustomError = new Error('Cannot read PKCS #12 PBE data block. Unsupported OID.')
12921301
error.oid = oid
12931302
throw error
12941303
}
12951304

12961305
// get PRF message digest
1297-
const prfAlgorithm = capture.prfOid || 'hmacWithSHA1'
1306+
const prfAlgorithm = validatedCapture.prfOid || 'hmacWithSHA1'
12981307
const md = prfAlgorithmToMessageDigest(prfAlgorithm)
12991308
const key = generatePkcs12Key(password, salt, 1, iterationCount, dkLen, md)
13001309
md.start()
13011310
const iv = generatePkcs12Key(password, salt, 2, iterationCount, dIvLen, md)
13021311

1303-
return cipherFn(key, iv)
1312+
return cipherFn(convertToString(key), convertToString(iv))
13041313
}
13051314

13061315
/**
@@ -1354,6 +1363,7 @@ export function prfAlgorithmToMessageDigest(prfAlgorithm: string): MessageDigest
13541363
switch (prfAlgorithm) {
13551364
case 'hmacWithSHA224':
13561365
factory = sha512
1366+
break
13571367
case 'hmacWithSHA1':
13581368
case 'hmacWithSHA256':
13591369
case 'hmacWithSHA384':

0 commit comments

Comments
 (0)