@@ -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