@@ -756,6 +756,18 @@ func ParsePrivateKey(pemBytes []byte) (Signer, error) {
756
756
return NewSignerFromKey (key )
757
757
}
758
758
759
+ // ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private
760
+ // key and passphrase. It supports the same keys as
761
+ // ParseRawPrivateKeyWithPassphrase.
762
+ func ParsePrivateKeyWithPassphrase (pemBytes , passPhrase []byte ) (Signer , error ) {
763
+ key , err := ParseRawPrivateKeyWithPassphrase (pemBytes , passPhrase )
764
+ if err != nil {
765
+ return nil , err
766
+ }
767
+
768
+ return NewSignerFromKey (key )
769
+ }
770
+
759
771
// encryptedBlock tells whether a private key is
760
772
// encrypted by examining its Proc-Type header
761
773
// for a mention of ENCRYPTED
@@ -790,6 +802,37 @@ func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
790
802
}
791
803
}
792
804
805
+ func ParseRawPrivateKeyWithPassphrase (pemBytes , passPhrase []byte ) (interface {}, error ) {
806
+ block , _ := pem .Decode (pemBytes )
807
+ if block == nil {
808
+ return nil , errors .New ("ssh: no key found" )
809
+ }
810
+ buf := block .Bytes
811
+
812
+ if encryptedBlock (block ) {
813
+ if x509 .IsEncryptedPEMBlock (block ) {
814
+ var err error
815
+ buf , err = x509 .DecryptPEMBlock (block , passPhrase )
816
+ if err != nil {
817
+ return nil , fmt .Errorf ("ssh: cannot decode encrypted private keys: %v" , err )
818
+ }
819
+ }
820
+ }
821
+
822
+ switch block .Type {
823
+ case "RSA PRIVATE KEY" :
824
+ return x509 .ParsePKCS1PrivateKey (buf )
825
+ case "EC PRIVATE KEY" :
826
+ return x509 .ParseECPrivateKey (buf )
827
+ case "DSA PRIVATE KEY" :
828
+ return ParseDSAPrivateKey (buf )
829
+ case "OPENSSH PRIVATE KEY" :
830
+ return parseOpenSSHPrivateKey (buf )
831
+ default :
832
+ return nil , fmt .Errorf ("ssh: unsupported key type %q" , block .Type )
833
+ }
834
+ }
835
+
793
836
// ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as
794
837
// specified by the OpenSSL DSA man page.
795
838
func ParseDSAPrivateKey (der []byte ) (* dsa.PrivateKey , error ) {
0 commit comments