@@ -208,3 +208,119 @@ func TestParsePrivateKeyPEM_InvalidPKCS8Key(t *testing.T) {
208208 t .Error ("Expected error for invalid PKCS8 key" )
209209 }
210210}
211+
212+ func TestParsePrivateKeyPEMWithPassword_EncryptedEC (t * testing.T ) {
213+ // Generate an EC key
214+ key , _ := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
215+ keyDER , _ := x509 .MarshalECPrivateKey (key )
216+
217+ // Encrypt the PEM block with a password
218+ password := []byte ("testpassword123" )
219+ //nolint:staticcheck // x509.EncryptPEMBlock is deprecated but needed for testing legacy format
220+ encryptedBlock , err := x509 .EncryptPEMBlock (rand .Reader , "EC PRIVATE KEY" , keyDER , password , x509 .PEMCipherAES256 )
221+ if err != nil {
222+ t .Fatalf ("Failed to encrypt PEM block: %v" , err )
223+ }
224+
225+ encryptedPEM := pem .EncodeToMemory (encryptedBlock )
226+
227+ // Test successful decryption with correct password
228+ parsed , err := ParsePrivateKeyPEMWithPassword (encryptedPEM , "testpassword123" )
229+ if err != nil {
230+ t .Fatalf ("Failed to parse encrypted EC key: %v" , err )
231+ }
232+ if _ , ok := parsed .(* ecdsa.PrivateKey ); ! ok {
233+ t .Error ("Expected ECDSA private key" )
234+ }
235+ }
236+
237+ func TestParsePrivateKeyPEMWithPassword_WrongPassword (t * testing.T ) {
238+ // Generate an EC key
239+ key , _ := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
240+ keyDER , _ := x509 .MarshalECPrivateKey (key )
241+
242+ // Encrypt the PEM block with a password
243+ password := []byte ("correctpassword" )
244+ //nolint:staticcheck // x509.EncryptPEMBlock is deprecated but needed for testing legacy format
245+ encryptedBlock , err := x509 .EncryptPEMBlock (rand .Reader , "EC PRIVATE KEY" , keyDER , password , x509 .PEMCipherAES256 )
246+ if err != nil {
247+ t .Fatalf ("Failed to encrypt PEM block: %v" , err )
248+ }
249+
250+ encryptedPEM := pem .EncodeToMemory (encryptedBlock )
251+
252+ // Test with wrong password
253+ _ , err = ParsePrivateKeyPEMWithPassword (encryptedPEM , "wrongpassword" )
254+ if err == nil {
255+ t .Error ("Expected error for wrong password" )
256+ }
257+ }
258+
259+ func TestParsePrivateKeyPEMWithPassword_EncryptedNoPassword (t * testing.T ) {
260+ // Generate an EC key
261+ key , _ := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
262+ keyDER , _ := x509 .MarshalECPrivateKey (key )
263+
264+ // Encrypt the PEM block with a password
265+ password := []byte ("testpassword" )
266+ //nolint:staticcheck // x509.EncryptPEMBlock is deprecated but needed for testing legacy format
267+ encryptedBlock , err := x509 .EncryptPEMBlock (rand .Reader , "EC PRIVATE KEY" , keyDER , password , x509 .PEMCipherAES256 )
268+ if err != nil {
269+ t .Fatalf ("Failed to encrypt PEM block: %v" , err )
270+ }
271+
272+ encryptedPEM := pem .EncodeToMemory (encryptedBlock )
273+
274+ // Test without providing password
275+ _ , err = ParsePrivateKeyPEMWithPassword (encryptedPEM , "" )
276+ if err == nil {
277+ t .Error ("Expected error when no password provided for encrypted key" )
278+ }
279+ if err .Error () != "private key is encrypted but no password provided (use -key-password)" {
280+ t .Errorf ("Unexpected error message: %v" , err )
281+ }
282+ }
283+
284+ func TestParsePrivateKeyPEMWithPassword_UnencryptedWithPassword (t * testing.T ) {
285+ // Generate an EC key (unencrypted)
286+ key , _ := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
287+ keyDER , _ := x509 .MarshalECPrivateKey (key )
288+ keyPEM := pem .EncodeToMemory (& pem.Block {
289+ Type : "EC PRIVATE KEY" ,
290+ Bytes : keyDER ,
291+ })
292+
293+ // Providing a password for unencrypted key should still work (password is ignored)
294+ parsed , err := ParsePrivateKeyPEMWithPassword (keyPEM , "unnecessarypassword" )
295+ if err != nil {
296+ t .Fatalf ("Failed to parse unencrypted key with password: %v" , err )
297+ }
298+ if _ , ok := parsed .(* ecdsa.PrivateKey ); ! ok {
299+ t .Error ("Expected ECDSA private key" )
300+ }
301+ }
302+
303+ func TestParsePrivateKeyPEMWithPassword_EncryptedRSA (t * testing.T ) {
304+ // Generate an RSA key
305+ key , _ := rsa .GenerateKey (rand .Reader , 2048 )
306+ keyDER := x509 .MarshalPKCS1PrivateKey (key )
307+
308+ // Encrypt the PEM block with a password
309+ password := []byte ("rsapassword" )
310+ //nolint:staticcheck // x509.EncryptPEMBlock is deprecated but needed for testing legacy format
311+ encryptedBlock , err := x509 .EncryptPEMBlock (rand .Reader , "RSA PRIVATE KEY" , keyDER , password , x509 .PEMCipherAES256 )
312+ if err != nil {
313+ t .Fatalf ("Failed to encrypt PEM block: %v" , err )
314+ }
315+
316+ encryptedPEM := pem .EncodeToMemory (encryptedBlock )
317+
318+ // Test successful decryption
319+ parsed , err := ParsePrivateKeyPEMWithPassword (encryptedPEM , "rsapassword" )
320+ if err != nil {
321+ t .Fatalf ("Failed to parse encrypted RSA key: %v" , err )
322+ }
323+ if _ , ok := parsed .(* rsa.PrivateKey ); ! ok {
324+ t .Error ("Expected RSA private key" )
325+ }
326+ }
0 commit comments