@@ -47,19 +47,23 @@ function testSignVerify(publicKey, privateKey) {
4747}
4848
4949// Constructs a regular expression for a PEM-encoded key with the given label.
50- function getRegExpForPEM ( label ) {
50+ function getRegExpForPEM ( label , cipher ) {
5151 const head = `\\-\\-\\-\\-\\-BEGIN ${ label } \\-\\-\\-\\-\\-` ;
52+ const rfc1421Header = cipher == null ? '' :
53+ `\nProc-Type: 4,ENCRYPTED\nDEK-Info: ${ cipher } ,[^\n]+\n` ;
5254 const body = '([a-zA-Z0-9\\+/=]{64}\n)*[a-zA-Z0-9\\+/=]{1,64}' ;
5355 const end = `\\-\\-\\-\\-\\-END ${ label } \\-\\-\\-\\-\\-` ;
54- return new RegExp ( `^${ head } \n${ body } \n${ end } \n$` ) ;
56+ return new RegExp ( `^${ head } ${ rfc1421Header } \n${ body } \n${ end } \n$` ) ;
5557}
5658
5759const pkcs1PubExp = getRegExpForPEM ( 'RSA PUBLIC KEY' ) ;
5860const pkcs1PrivExp = getRegExpForPEM ( 'RSA PRIVATE KEY' ) ;
61+ const pkcs1EncExp = ( cipher ) => getRegExpForPEM ( 'RSA PRIVATE KEY' , cipher ) ;
5962const spkiExp = getRegExpForPEM ( 'PUBLIC KEY' ) ;
6063const pkcs8Exp = getRegExpForPEM ( 'PRIVATE KEY' ) ;
6164const pkcs8EncExp = getRegExpForPEM ( 'ENCRYPTED PRIVATE KEY' ) ;
6265const sec1Exp = getRegExpForPEM ( 'EC PRIVATE KEY' ) ;
66+ const sec1EncExp = ( cipher ) => getRegExpForPEM ( 'EC PRIVATE KEY' , cipher ) ;
6367
6468// Since our own APIs only accept PEM, not DER, we need to convert DER to PEM
6569// for testing.
@@ -137,6 +141,42 @@ function convertDERToPEM(label, der) {
137141 testEncryptDecrypt ( publicKey , privateKey ) ;
138142 testSignVerify ( publicKey , privateKey ) ;
139143 } ) ) ;
144+
145+ // Now do the same with an encrypted private key.
146+ generateKeyPair ( 'rsa' , {
147+ publicExponent : 0x10001 ,
148+ modulusLength : 4096 ,
149+ publicKeyEncoding : {
150+ type : 'pkcs1' ,
151+ format : 'der'
152+ } ,
153+ privateKeyEncoding : {
154+ type : 'pkcs1' ,
155+ format : 'pem' ,
156+ cipher : 'aes-256-cbc' ,
157+ passphrase : 'secret'
158+ }
159+ } , common . mustCall ( ( err , publicKeyDER , privateKey ) => {
160+ assert . ifError ( err ) ;
161+
162+ // The public key is encoded as DER (which is binary) instead of PEM. We
163+ // will still need to convert it to PEM for testing.
164+ assert ( Buffer . isBuffer ( publicKeyDER ) ) ;
165+ const publicKey = convertDERToPEM ( 'RSA PUBLIC KEY' , publicKeyDER ) ;
166+ assertApproximateSize ( publicKey , 720 ) ;
167+
168+ assert . strictEqual ( typeof privateKey , 'string' ) ;
169+ assert ( pkcs1EncExp ( 'AES-256-CBC' ) . test ( privateKey ) ) ;
170+
171+ // Since the private key is encrypted, signing shouldn't work anymore.
172+ assert . throws ( ( ) => {
173+ testSignVerify ( publicKey , privateKey ) ;
174+ } , / b a d d e c r y p t | a s n 1 e n c o d i n g r o u t i n e s / ) ;
175+
176+ const key = { key : privateKey , passphrase : 'secret' } ;
177+ testEncryptDecrypt ( publicKey , key ) ;
178+ testSignVerify ( publicKey , key ) ;
179+ } ) ) ;
140180}
141181
142182{
@@ -203,6 +243,36 @@ function convertDERToPEM(label, der) {
203243
204244 testSignVerify ( publicKey , privateKey ) ;
205245 } ) ) ;
246+
247+ // Do the same with an encrypted private key.
248+ generateKeyPair ( 'ec' , {
249+ namedCurve : 'prime256v1' ,
250+ paramEncoding : 'named' ,
251+ publicKeyEncoding : {
252+ type : 'spki' ,
253+ format : 'pem'
254+ } ,
255+ privateKeyEncoding : {
256+ type : 'sec1' ,
257+ format : 'pem' ,
258+ cipher : 'aes-128-cbc' ,
259+ passphrase : 'secret'
260+ }
261+ } , common . mustCall ( ( err , publicKey , privateKey ) => {
262+ assert . ifError ( err ) ;
263+
264+ assert . strictEqual ( typeof publicKey , 'string' ) ;
265+ assert ( spkiExp . test ( publicKey ) ) ;
266+ assert . strictEqual ( typeof privateKey , 'string' ) ;
267+ assert ( sec1EncExp ( 'AES-128-CBC' ) . test ( privateKey ) ) ;
268+
269+ // Since the private key is encrypted, signing shouldn't work anymore.
270+ assert . throws ( ( ) => {
271+ testSignVerify ( publicKey , privateKey ) ;
272+ } , / b a d d e c r y p t | a s n 1 e n c o d i n g r o u t i n e s / ) ;
273+
274+ testSignVerify ( publicKey , { key : privateKey , passphrase : 'secret' } ) ;
275+ } ) ) ;
206276}
207277
208278{
@@ -640,7 +710,7 @@ function convertDERToPEM(label, der) {
640710 } ) ;
641711 }
642712
643- // Attempting to encrypt a non-PKCS#8 key.
713+ // Attempting to encrypt a DER-encoded, non-PKCS#8 key.
644714 for ( const type of [ 'pkcs1' , 'sec1' ] ) {
645715 common . expectsError ( ( ) => {
646716 generateKeyPairSync ( type === 'pkcs1' ? 'rsa' : 'ec' , {
@@ -649,7 +719,7 @@ function convertDERToPEM(label, der) {
649719 publicKeyEncoding : { type : 'spki' , format : 'pem' } ,
650720 privateKeyEncoding : {
651721 type,
652- format : 'pem ' ,
722+ format : 'der ' ,
653723 cipher : 'aes-128-cbc' ,
654724 passphrase : 'hello'
655725 }
0 commit comments