Skip to content

Commit

Permalink
ssh: reject unsupported DSA key sizes
Browse files Browse the repository at this point in the history
Fixes golang/go#19424.

Change-Id: I73370603dd612979420d608b73d67e673a52362b
Reviewed-on: https://go-review.googlesource.com/62870
Run-TryBot: Han-Wen Nienhuys <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Filippo Valsorda <[email protected]>
Reviewed-by: Adam Langley <[email protected]>
  • Loading branch information
desdeel2d0m authored and hanwen committed Sep 12, 2017
1 parent 5d25835 commit 7fc05fc
Showing 1 changed file with 34 additions and 9 deletions.
43 changes: 34 additions & 9 deletions ssh/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 7fc05fc

Please sign in to comment.