diff options
| author | Han-Wen Nienhuys <hanwen@google.com> | 2017-09-11 11:58:25 +0200 |
|---|---|---|
| committer | Han-Wen Nienhuys <hanwen@google.com> | 2017-09-12 12:23:26 +0000 |
| commit | 88e95fbb56610f02dbc78ebc3b207bec8cf56b86 (patch) | |
| tree | 39b2eb94735fdd9930676358bdd9adfcc907f4da /ssh/keys.go | |
| parent | 74b34b9dd60829a9fcaf56a59e81c3877a8ecd2c (diff) | |
| download | go-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.go | 43 |
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(¶m); 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 |
