ssh: signal incorrect private key passwords with x509.IncorrectPasswordError

Fixes golang/go#20781

Change-Id: Iae42fff3c9b0b9984509e44a92f9bc99a1a12470
Reviewed-on: https://go-review.googlesource.com/46439
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/ssh/keys.go b/ssh/keys.go
index 4c8b1a8..7a8756a 100644
--- a/ssh/keys.go
+++ b/ssh/keys.go
@@ -802,6 +802,9 @@
 	}
 }
 
+// ParseRawPrivateKeyWithPassphrase returns a private key decrypted with
+// passphrase from a PEM encoded private key. If wrong passphrase, return
+// x509.IncorrectPasswordError.
 func ParseRawPrivateKeyWithPassphrase(pemBytes, passPhrase []byte) (interface{}, error) {
 	block, _ := pem.Decode(pemBytes)
 	if block == nil {
@@ -814,6 +817,9 @@
 			var err error
 			buf, err = x509.DecryptPEMBlock(block, passPhrase)
 			if err != nil {
+				if err == x509.IncorrectPasswordError {
+					return nil, err
+				}
 				return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err)
 			}
 		}
diff --git a/ssh/keys_test.go b/ssh/keys_test.go
index 2bacc52..20ab954 100644
--- a/ssh/keys_test.go
+++ b/ssh/keys_test.go
@@ -11,6 +11,7 @@
 	"crypto/elliptic"
 	"crypto/rand"
 	"crypto/rsa"
+	"crypto/x509"
 	"encoding/base64"
 	"fmt"
 	"reflect"
@@ -165,6 +166,12 @@
 			t.Errorf("Verify failed: %v", err)
 		}
 	}
+
+	tt := testdata.PEMEncryptedKeys[0]
+	_, err := ParsePrivateKeyWithPassphrase(tt.PEMBytes, []byte("incorrect"))
+	if err != x509.IncorrectPasswordError {
+		t.Fatalf("got %v want IncorrectPasswordError", err)
+	}
 }
 
 func TestParseDSA(t *testing.T) {