Refactor key parsing, marshaling, and serialization to be a bit more flexible R=agl, dave, djm CC=golang-dev https://golang.org/cl/5650067
121 lines
2.6 KiB
Go
121 lines
2.6 KiB
Go
// Copyright 2012 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package ssh
|
|
|
|
import (
|
|
"crypto/dsa"
|
|
"crypto/rsa"
|
|
"math/big"
|
|
)
|
|
|
|
// parsePubKey parses a public key according to RFC 4253, section 6.6.
|
|
func parsePubKey(in []byte) (out interface{}, rest []byte, ok bool) {
|
|
algo, in, ok := parseString(in)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
switch string(algo) {
|
|
case hostAlgoRSA:
|
|
return parseRSA(in)
|
|
case hostAlgoDSA:
|
|
return parseDSA(in)
|
|
case hostAlgoRSACertV01, hostAlgoDSACertV01:
|
|
return parseOpenSSHCertV01(in, string(algo))
|
|
}
|
|
panic("ssh: unknown public key type")
|
|
}
|
|
|
|
// parseRSA parses an RSA key according to RFC 4253, section 6.6.
|
|
func parseRSA(in []byte) (out *rsa.PublicKey, rest []byte, ok bool) {
|
|
key := new(rsa.PublicKey)
|
|
|
|
bigE, in, ok := parseInt(in)
|
|
if !ok || bigE.BitLen() > 24 {
|
|
return
|
|
}
|
|
e := bigE.Int64()
|
|
if e < 3 || e&1 == 0 {
|
|
ok = false
|
|
return
|
|
}
|
|
key.E = int(e)
|
|
|
|
if key.N, in, ok = parseInt(in); !ok {
|
|
return
|
|
}
|
|
|
|
ok = true
|
|
return key, in, ok
|
|
}
|
|
|
|
// parseDSA parses an DSA key according to RFC 4253, section 6.6.
|
|
func parseDSA(in []byte) (out *dsa.PublicKey, rest []byte, ok bool) {
|
|
key := new(dsa.PublicKey)
|
|
|
|
if key.P, in, ok = parseInt(in); !ok {
|
|
return
|
|
}
|
|
|
|
if key.Q, in, ok = parseInt(in); !ok {
|
|
return
|
|
}
|
|
|
|
if key.G, in, ok = parseInt(in); !ok {
|
|
return
|
|
}
|
|
|
|
if key.Y, in, ok = parseInt(in); !ok {
|
|
return
|
|
}
|
|
|
|
ok = true
|
|
return key, in, ok
|
|
}
|
|
|
|
// marshalPrivRSA serializes an RSA private key according to RFC 4253, section 6.6.
|
|
func marshalPrivRSA(priv *rsa.PrivateKey) []byte {
|
|
e := new(big.Int).SetInt64(int64(priv.E))
|
|
length := stringLength([]byte(hostAlgoRSA))
|
|
length += intLength(e)
|
|
length += intLength(priv.N)
|
|
|
|
ret := make([]byte, length)
|
|
r := marshalString(ret, []byte(hostAlgoRSA))
|
|
r = marshalInt(r, e)
|
|
r = marshalInt(r, priv.N)
|
|
|
|
return ret
|
|
}
|
|
|
|
// marshalPubRSA serializes an RSA public key according to RFC 4253, section 6.6.
|
|
func marshalPubRSA(key *rsa.PublicKey) []byte {
|
|
e := new(big.Int).SetInt64(int64(key.E))
|
|
length := intLength(e)
|
|
length += intLength(key.N)
|
|
|
|
ret := make([]byte, length)
|
|
r := marshalInt(ret, e)
|
|
r = marshalInt(r, key.N)
|
|
|
|
return ret
|
|
}
|
|
|
|
// marshalPubDSA serializes an DSA public key according to RFC 4253, section 6.6.
|
|
func marshalPubDSA(key *dsa.PublicKey) []byte {
|
|
length := intLength(key.P)
|
|
length += intLength(key.Q)
|
|
length += intLength(key.G)
|
|
length += intLength(key.Y)
|
|
|
|
ret := make([]byte, length)
|
|
r := marshalInt(ret, key.P)
|
|
r = marshalInt(r, key.Q)
|
|
r = marshalInt(r, key.G)
|
|
marshalInt(r, key.Y)
|
|
|
|
return ret
|
|
}
|