aboutsummaryrefslogtreecommitdiff
path: root/ssh/keys.go
diff options
context:
space:
mode:
authorHan-Wen Nienhuys <hanwen@google.com>2017-09-11 11:58:25 +0200
committerHan-Wen Nienhuys <hanwen@google.com>2017-09-12 12:23:26 +0000
commit88e95fbb56610f02dbc78ebc3b207bec8cf56b86 (patch)
tree39b2eb94735fdd9930676358bdd9adfcc907f4da /ssh/keys.go
parent74b34b9dd60829a9fcaf56a59e81c3877a8ecd2c (diff)
downloadgo-x-crypto-88e95fbb56610f02dbc78ebc3b207bec8cf56b86.tar.xz
ssh: reject unsupported DSA key sizes
Fixes golang/go#19424. Change-Id: I73370603dd612979420d608b73d67e673a52362b Reviewed-on: https://go-review.googlesource.com/62870 Run-TryBot: Han-Wen Nienhuys <hanwen@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Filippo Valsorda <hi@filippo.io> Reviewed-by: Adam Langley <agl@golang.org>
Diffstat (limited to 'ssh/keys.go')
-rw-r--r--ssh/keys.go43
1 files changed, 34 insertions, 9 deletions
diff --git a/ssh/keys.go b/ssh/keys.go
index 7a8756a..b682c17 100644
--- a/ssh/keys.go
+++ b/ssh/keys.go
@@ -367,6 +367,17 @@ func (r *dsaPublicKey) Type() string {
return "ssh-dss"
}
+func checkDSAParams(param *dsa.Parameters) error {
+ // SSH specifies FIPS 186-2, which only provided a single size
+ // (1024 bits) DSA key. FIPS 186-3 allows for larger key
+ // sizes, which would confuse SSH.
+ if l := param.P.BitLen(); l != 1024 {
+ return fmt.Errorf("ssh: unsupported DSA key size %d", l)
+ }
+
+ return nil
+}
+
// parseDSA parses an DSA key according to RFC 4253, section 6.6.
func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
var w struct {
@@ -377,13 +388,18 @@ func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
return nil, nil, err
}
+ param := dsa.Parameters{
+ P: w.P,
+ Q: w.Q,
+ G: w.G,
+ }
+ if err := checkDSAParams(&param); err != nil {
+ return nil, nil, err
+ }
+
key := &dsaPublicKey{
- Parameters: dsa.Parameters{
- P: w.P,
- Q: w.Q,
- G: w.G,
- },
- Y: w.Y,
+ Parameters: param,
+ Y: w.Y,
}
return key, w.Rest, nil
}
@@ -630,19 +646,28 @@ func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
}
// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
-// *ecdsa.PrivateKey or any other crypto.Signer and returns a corresponding
-// Signer instance. ECDSA keys must use P-256, P-384 or P-521.
+// *ecdsa.PrivateKey or any other crypto.Signer and returns a
+// corresponding Signer instance. ECDSA keys must use P-256, P-384 or
+// P-521. DSA keys must use parameter size L1024N160.
func NewSignerFromKey(key interface{}) (Signer, error) {
switch key := key.(type) {
case crypto.Signer:
return NewSignerFromSigner(key)
case *dsa.PrivateKey:
- return &dsaPrivateKey{key}, nil
+ return newDSAPrivateKey(key)
default:
return nil, fmt.Errorf("ssh: unsupported key type %T", key)
}
}
+func newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {
+ if err := checkDSAParams(&key.PublicKey.Parameters); err != nil {
+ return nil, err
+ }
+
+ return &dsaPrivateKey{key}, nil
+}
+
type wrappedSigner struct {
signer crypto.Signer
pubKey PublicKey