go.crypto/ssh: parse DSA private keys too.

R=golang-dev, agl
CC=golang-dev
https://golang.org/cl/13966043
This commit is contained in:
Han-Wen Nienhuys
2013-09-26 11:17:52 -04:00
committed by Adam Langley
parent 73e99326fb
commit 4e0581245c
2 changed files with 73 additions and 5 deletions
+42 -5
View File
@@ -12,6 +12,7 @@ import (
"crypto/elliptic"
"crypto/rsa"
"crypto/x509"
"encoding/asn1"
"encoding/base64"
"encoding/pem"
"errors"
@@ -557,8 +558,8 @@ func NewPublicKey(k interface{}) (PublicKey, error) {
return sshKey, nil
}
// ParsePublicKey parses a PEM encoded private key. Currently, only
// PKCS#1, RSA and ECDSA private keys are supported.
// ParsePublicKey parses a PEM encoded private key. It supports
// PKCS#1, RSA, DSA and ECDSA private keys.
func ParsePrivateKey(pemBytes []byte) (Signer, error) {
block, _ := pem.Decode(pemBytes)
if block == nil {
@@ -579,12 +580,48 @@ func ParsePrivateKey(pemBytes []byte) (Signer, error) {
return nil, err
}
rawkey = ec
// TODO(hanwen): find doc for format and implement PEM parsing
// for DSA keys.
case "DSA PRIVATE KEY":
ec, err := parseDSAPrivate(block.Bytes)
if err != nil {
return nil, err
}
rawkey = ec
default:
return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
}
return NewSignerFromKey(rawkey)
}
// parseDSAPrivate parses a DSA key in ASN.1 DER encoding, as
// documented in the OpenSSL DSA manpage.
// TODO(hanwen): move this in to crypto/x509 after the Go 1.2 freeze.
func parseDSAPrivate(p []byte) (*dsa.PrivateKey, error) {
k := struct {
Version int
P *big.Int
Q *big.Int
G *big.Int
Priv *big.Int
Pub *big.Int
}{}
rest, err := asn1.Unmarshal(p, &k)
if err != nil {
return nil, errors.New("ssh: failed to parse DSA key: " + err.Error())
}
if len(rest) > 0 {
return nil, errors.New("ssh: garbage after DSA key")
}
return &dsa.PrivateKey{
PublicKey: dsa.PublicKey{
Parameters: dsa.Parameters{
P: k.P,
Q: k.Q,
G: k.G,
},
Y: k.Priv,
},
X: k.Pub,
}, nil
}