@@ -23,15 +23,19 @@ import type { BlockCipher } from './cipher'
2323import type { MessageDigest } from './sha1'
2424import { aes } from './aes'
2525import { asn1 } from './asn1'
26+ import { wrapRsaPrivateKey , privateKeyToAsn1 , privateKeyFromAsn1 } from './rsa'
2627import { createCipher } from './cipher'
28+ import { sha1 } from './sha1'
2729import { des } from './des'
2830import { md5 } from './md5'
2931import { oids } from './oids'
3032import { pbkdf2 } from './pbkdf2'
3133import { getBytesSync } from './random'
3234import { rc2 } from './rc2'
35+ import { pki } from './pki'
3336import { sha512 } from './sha512'
34- import { ByteBuffer , createBuffer , hexToBytes } from './utils'
37+ import { ByteBuffer , bytesToHex , createBuffer , hexToBytes } from './utils'
38+ import { pem } from './pem'
3539
3640// validator for an EncryptedPrivateKeyInfo structure
3741// Note: Currently only works w/algorithm params
@@ -358,7 +362,7 @@ export function encryptPrivateKeyInfo(obj: any, password: any, options: any): Bu
358362 *
359363 * @return the ASN.1 PrivateKeyInfo on success, null on failure.
360364 */
361- pki . decryptPrivateKeyInfo = function ( obj , password ) {
365+ export function decryptPrivateKeyInfo ( obj : any , password : any ) : any {
362366 let rval = null
363367
364368 // get PBE params
@@ -373,15 +377,14 @@ pki.decryptPrivateKeyInfo = function (obj, password) {
373377
374378 // get cipher
375379 const oid = asn1 . derToOid ( capture . encryptionOid )
376- const cipher = pki . pbe . getCipher ( oid , capture . encryptionParams , password )
380+ const cipher = getCipher ( oid , capture . encryptionParams , password )
377381
378382 // get encrypted data
379383 const encrypted = createBuffer ( capture . encryptedData )
380384
381385 cipher . update ( encrypted )
382- if ( cipher . finish ( ) ) {
386+ if ( cipher . finish ( ) )
383387 rval = asn1 . fromDer ( cipher . output )
384- }
385388
386389 return rval
387390}
@@ -394,13 +397,14 @@ pki.decryptPrivateKeyInfo = function (obj, password) {
394397 *
395398 * @return the PEM-formatted encrypted private key.
396399 */
397- pki . encryptedPrivateKeyToPem = function ( epki , maxline ) {
400+ export function encryptedPrivateKeyToPem ( epki : any , maxline : number ) : string {
398401 // convert to DER, then PEM-encode
399402 const msg = {
400403 type : 'ENCRYPTED PRIVATE KEY' ,
401404 body : asn1 . toDer ( epki ) . getBytes ( ) ,
402405 }
403- return forge . pem . encode ( msg , { maxline } )
406+
407+ return pem . encode ( msg , { maxline } )
404408}
405409
406410/**
@@ -411,8 +415,8 @@ pki.encryptedPrivateKeyToPem = function (epki, maxline) {
411415 *
412416 * @return the ASN.1 EncryptedPrivateKeyInfo.
413417 */
414- pki . encryptedPrivateKeyFromPem = function ( pem ) {
415- const msg = forge . pem . decode ( pem ) [ 0 ]
418+ export function encryptedPrivateKeyFromPem ( pem : string ) : any {
419+ const msg = pem . decode ( pem ) [ 0 ]
416420
417421 if ( msg . type !== 'ENCRYPTED PRIVATE KEY' ) {
418422 const error = new Error ( 'Could not convert encrypted private key from PEM; '
@@ -445,31 +449,31 @@ pki.encryptedPrivateKeyFromPem = function (pem) {
445449 *
446450 * @param rsaKey the RSA key to encrypt.
447451 * @param password the password to use.
448- * @param options:
449- * algorithm: the encryption algorithm to use
450- * ('aes128', 'aes192', 'aes256', '3des', 'des').
451- * count: the iteration count to use.
452- * saltSize: the salt size to use.
453- * legacy: output an old non-PKCS#8 PEM-encrypted+encapsulated
454- * headers (DEK-Info) private key.
452+ * @param options options for the encryption
453+ * @param options.algorithm the encryption algorithm to use ('aes128', 'aes192', 'aes256', '3des', 'des').
454+ * @param options.count the iteration count to use.
455+ * @param options.saltSize the salt size to use.
456+ * @param options.legacy output an old non-PKCS#8 PEM-encrypted+encapsulated headers (DEK-Info) private key.
455457 *
456458 * @return the PEM-encoded ASN.1 EncryptedPrivateKeyInfo.
457459 */
458- pki . encryptRsaPrivateKey = function ( rsaKey , password , options ) {
460+ export function encryptRsaPrivateKey ( rsaKey : any , password : any , options : any ) : string {
459461 // standard PKCS#8
460462 options = options || { }
461463 if ( ! options . legacy ) {
462464 // encrypt PrivateKeyInfo
463- let rval = pki . wrapRsaPrivateKey ( pki . privateKeyToAsn1 ( rsaKey ) )
464- rval = pki . encryptPrivateKeyInfo ( rval , password , options )
465- return pki . encryptedPrivateKeyToPem ( rval )
465+ let rval = wrapRsaPrivateKey ( privateKeyToAsn1 ( rsaKey ) )
466+ rval = encryptPrivateKeyInfo ( rval , password , options )
467+
468+ return encryptedPrivateKeyToPem ( rval )
466469 }
467470
468471 // legacy non-PKCS#8
469472 let algorithm
470473 let iv
471474 let dkLen
472475 let cipherFn
476+
473477 switch ( options . algorithm ) {
474478 case 'aes128' :
475479 algorithm = 'AES-128-CBC'
@@ -512,7 +516,7 @@ pki.encryptRsaPrivateKey = function (rsaKey, password, options) {
512516 const dk = opensslDeriveBytes ( password , iv . substr ( 0 , 8 ) , dkLen )
513517 const cipher = cipherFn ( dk )
514518 cipher . start ( iv )
515- cipher . update ( asn1 . toDer ( pki . privateKeyToAsn1 ( rsaKey ) ) )
519+ cipher . update ( asn1 . toDer ( privateKeyToAsn1 ( rsaKey ) ) )
516520 cipher . finish ( )
517521
518522 const msg = {
@@ -523,11 +527,11 @@ pki.encryptRsaPrivateKey = function (rsaKey, password, options) {
523527 } ,
524528 dekInfo : {
525529 algorithm,
526- parameters : forge . util . bytesToHex ( iv ) . toUpperCase ( ) ,
530+ parameters : bytesToHex ( iv ) . toUpperCase ( ) ,
527531 } ,
528- body : cipher . output . getBytes ( ) ,
532+ body : cipher . output ? .getBytes ( ) ,
529533 }
530- return forge . pem . encode ( msg )
534+ return pem . encode ( msg )
531535}
532536
533537/**
@@ -538,10 +542,10 @@ pki.encryptRsaPrivateKey = function (rsaKey, password, options) {
538542 *
539543 * @return the RSA key on success, null on failure.
540544 */
541- pki . decryptRsaPrivateKey = function ( pem , password ) {
545+ export function decryptRsaPrivateKey ( pem : string , password : string ) : any {
542546 let rval = null
543547
544- const msg = forge . pem . decode ( pem ) [ 0 ]
548+ const msg = pem . decode ( pem ) [ 0 ]
545549
546550 if ( msg . type !== 'ENCRYPTED PRIVATE KEY'
547551 && msg . type !== 'PRIVATE KEY'
@@ -585,13 +589,13 @@ pki.decryptRsaPrivateKey = function (pem, password) {
585589 case 'RC2-64-CBC' :
586590 dkLen = 8
587591 cipherFn = function ( key ) {
588- return forge . rc2 . createDecryptionCipher ( key , 64 )
592+ return rc2 . createDecryptionCipher ( key , 64 )
589593 }
590594 break
591595 case 'RC2-128-CBC' :
592596 dkLen = 16
593597 cipherFn = function ( key ) {
594- return forge . rc2 . createDecryptionCipher ( key , 128 )
598+ return rc2 . createDecryptionCipher ( key , 128 )
595599 }
596600 break
597601 default :
@@ -607,28 +611,25 @@ pki.decryptRsaPrivateKey = function (pem, password) {
607611 const cipher = cipherFn ( dk )
608612 cipher . start ( iv )
609613 cipher . update ( createBuffer ( msg . body ) )
610- if ( cipher . finish ( ) ) {
611- rval = cipher . output . getBytes ( )
612- }
613- else {
614+
615+ if ( cipher . finish ( ) )
616+ rval = cipher . output ?. getBytes ( )
617+ else
614618 return rval
615- }
619+ }
616620 }
617621 else {
618622 rval = msg . body
619623 }
620624
621- if ( msg . type === 'ENCRYPTED PRIVATE KEY' ) {
622- rval = pki . decryptPrivateKeyInfo ( asn1 . fromDer ( rval ) , password )
623- }
624- else {
625+ if ( msg . type === 'ENCRYPTED PRIVATE KEY' )
626+ rval = decryptPrivateKeyInfo ( asn1 . fromDer ( rval ) , password )
627+ else
625628 // decryption already performed above
626629 rval = asn1 . fromDer ( rval )
627- }
628630
629- if ( rval !== null ) {
630- rval = pki . privateKeyFromAsn1 ( rval )
631- }
631+ if ( rval !== null )
632+ rval = privateKeyFromAsn1 ( rval )
632633
633634 return rval
634635}
@@ -650,10 +651,10 @@ export function generatePkcs12Key(password: string, salt: string, id: number, it
650651 let j , l
651652
652653 if ( typeof md === 'undefined' || md === null ) {
653- if ( ! ( 'sha1' in forge . md ) ) {
654+ if ( ! ( 'sha1' in md ) )
654655 throw new Error ( '"sha1" hash algorithm unavailable.' )
655- }
656- md = forge . md . sha1 . create ( )
656+
657+ md = sha1 . create ( )
657658 }
658659
659660 const u = md . digestLength
@@ -663,51 +664,65 @@ export function generatePkcs12Key(password: string, salt: string, id: number, it
663664 /* Convert password to Unicode byte buffer + trailing 0-byte. */
664665 const passBuf = new ByteBuffer ( )
665666 if ( password !== null && password !== undefined ) {
666- for ( l = 0 ; l < password . length ; l ++ ) {
667+ for ( l = 0 ; l < password . length ; l ++ )
667668 passBuf . putInt16 ( password . charCodeAt ( l ) )
668- }
669+
669670 passBuf . putInt16 ( 0 )
670671 }
671672
672- /* Length of salt and password in BYTES. */
673+ /**
674+ * Length of salt and password in BYTES.
675+ */
673676 const p = passBuf . length ( )
674677 const s = salt . length ( )
675678
676- /* 1. Construct a string, D (the "diversifier"), by concatenating
677- v copies of ID. */
679+ /**
680+ * 1. Construct a string, D (the "diversifier"), by concatenating v copies of ID.
681+ */
678682 const D = new ByteBuffer ( )
679683 D . fillWithByte ( id , v )
680684
681- /* 2. Concatenate copies of the salt together to create a string S of length
682- v * ceil(s / v) bytes (the final copy of the salt may be trunacted
683- to create S).
684- Note that if the salt is the empty string, then so is S. */
685+ /**
686+ * 2. Concatenate copies of the salt together to create a string S of length
687+ * v * ceil(s / v) bytes (the final copy of the salt may be truncated to create S).
688+ * Note that if the salt is the empty string, then so is S.
689+ */
685690 const Slen = v * Math . ceil ( s / v )
686691 const S = new ByteBuffer ( )
687692 for ( l = 0 ; l < Slen ; l ++ ) {
688693 S . putByte ( salt . at ( l % s ) )
689694 }
690695
691- /* 3. Concatenate copies of the password together to create a string P of
692- length v * ceil(p / v) bytes (the final copy of the password may be
693- truncated to create P).
694- Note that if the password is the empty string, then so is P. */
696+ /**
697+ * 3. Concatenate copies of the password together to create a string P of
698+ * length v * ceil(p / v) bytes (the final copy of the password may be
699+ * truncated to create P).
700+ * Note that if the password is the empty string, then so is P.
701+ */
695702 const Plen = v * Math . ceil ( p / v )
696703 const P = new ByteBuffer ( )
697704 for ( l = 0 ; l < Plen ; l ++ ) {
698705 P . putByte ( passBuf . at ( l % p ) )
699706 }
700707
701- /* 4. Set I=S||P to be the concatenation of S and P. */
708+ /**
709+ * 4. Set I=S||P to be the concatenation of S and P.
710+ */
702711 let I = S
703712 I . putBuffer ( P )
704713
705- /* 5. Set c=ceil(n / u). */
714+ /**
715+ * 5. Set c=ceil(n / u).
716+ */
706717 const c = Math . ceil ( n / u )
707718
708- /* 6. For i=1, 2, ..., c, do the following: */
719+ /**
720+ * 6. For i=1, 2, ..., c, do the following:
721+ */
709722 for ( let i = 1 ; i <= c ; i ++ ) {
710- /* a) Set Ai=H^r(D||I). (l.e. the rth hash of D||I, H(H(H(...H(D||I)))) */
723+ /**
724+ * a) Set Ai=H^r(D||I). (l.e. the rth hash of D||I, H(H(H(...H(D||I))))
725+ */
711726 let buf = new ByteBuffer ( )
712727 buf . putBytes ( D . bytes ( ) )
713728 buf . putBytes ( I . bytes ( ) )
@@ -717,16 +732,20 @@ export function generatePkcs12Key(password: string, salt: string, id: number, it
717732 buf = md . digest ( )
718733 }
719734
720- /* b) Concatenate copies of Ai to create a string B of length v bytes (the
721- final copy of Ai may be truncated to create B). */
735+ /**
736+ * b) Concatenate copies of Ai to create a string B of length v bytes (the
737+ * final copy of Ai may be truncated to create B).
738+ */
722739 const B = new ByteBuffer ( )
723740 for ( l = 0 ; l < v ; l ++ ) {
724741 B . putByte ( buf . at ( l % u ) )
725742 }
726743
727- /* c) Treating I as a concatenation I0, I1, ..., Ik-1 of v-byte blocks,
728- where k=ceil(s / v) + ceil(p / v), modify I by setting
729- Ij=(Ij+B+1) mod 2v for each j. */
744+ /**
745+ * c) Treating I as a concatenation I0, I1, ..., Ik-1 of v-byte blocks,
746+ * where k=ceil(s / v) + ceil(p / v), modify I by setting
747+ * Ij=(Ij+B+1) mod 2v for each j.
748+ */
730749 const k = Math . ceil ( s / v ) + Math . ceil ( p / v )
731750 const Inew = new ByteBuffer ( )
732751 for ( j = 0 ; j < k ; j ++ ) {
@@ -741,11 +760,14 @@ export function generatePkcs12Key(password: string, salt: string, id: number, it
741760 }
742761 I = Inew
743762
744- /* Add Ai to A. */
763+ /**
764+ * Add Ai to A.
765+ */
745766 result . putBuffer ( buf )
746767 }
747768
748769 result . truncate ( result . length ( ) - n )
770+
749771 return result
750772}
751773
@@ -954,9 +976,8 @@ export function opensslDeriveBytes(password: string, salt: string, dkLen: number
954976 md = md5 . create ( )
955977 }
956978
957- if ( salt === null ) {
979+ if ( salt === null )
958980 salt = ''
959- }
960981
961982 const digests = [ hash ( md , password + salt ) ]
962983
@@ -977,7 +998,6 @@ export function prfOidToMessageDigest(prfOid: string): MessageDigest {
977998 if ( ! prfOid ) {
978999 prfAlgorithm = 'hmacWithSHA1'
9791000 }
980-
9811001 else {
9821002 prfAlgorithm = oids [ asn1 . derToOid ( prfOid ) ]
9831003 if ( ! prfAlgorithm ) {
@@ -993,6 +1013,7 @@ export function prfOidToMessageDigest(prfOid: string): MessageDigest {
9931013 throw error
9941014 }
9951015 }
1016+
9961017 return prfAlgorithmToMessageDigest ( prfAlgorithm )
9971018}
9981019
@@ -1020,9 +1041,10 @@ export function prfAlgorithmToMessageDigest(prfAlgorithm: string): MessageDigest
10201041 ]
10211042 throw error
10221043 }
1023- if ( ! factory || ! ( prfAlgorithm in factory ) ) {
1044+
1045+ if ( ! factory || ! ( prfAlgorithm in factory ) )
10241046 throw new Error ( `Unknown hash algorithm: ${ prfAlgorithm } ` )
1025- }
1047+
10261048 return factory [ prfAlgorithm ] . create ( )
10271049}
10281050
@@ -1035,6 +1057,7 @@ export function createPbkdf2Params(salt: string, countBytes: Buffer, dkLen: numb
10351057 false ,
10361058 salt ,
10371059 ) ,
1060+
10381061 // iteration count
10391062 asn1 . create ( asn1 . Class . UNIVERSAL , asn1 . Type . INTEGER , false , countBytes . getBytes ( ) ) ,
10401063 ] )
0 commit comments