go.crypto/ssh: Miscellaneous changes up for discussion.
Export key and certificate algorithm names. Switch from string literals over to using the constants for any key/cert algorithm references. Make URL references visible in the godoc web display. Standardize url reference names with surrounding []. R=dave, agl, jonathan.mark.pittman CC=golang-dev https://golang.org/cl/6944047
This commit is contained in:
committed by
Adam Langley
parent
97c15b3da8
commit
54c65aebf4
+10
-13
@@ -4,9 +4,6 @@
|
||||
|
||||
package ssh
|
||||
|
||||
// References
|
||||
// PROTOCOL.agent: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
@@ -14,7 +11,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// See PROTOCOL.agent, section 3.
|
||||
// See [PROTOCOL.agent], section 3.
|
||||
const (
|
||||
// 3.2 Requests from client to agent for protocol 2 key operations
|
||||
agentRequestIdentities = 11
|
||||
@@ -50,34 +47,34 @@ const maxAgentResponseBytes = 16 << 20
|
||||
|
||||
// Agent messages:
|
||||
// These structures mirror the wire format of the corresponding ssh agent
|
||||
// messages found in PROTOCOL.agent.
|
||||
// messages found in [PROTOCOL.agent].
|
||||
|
||||
type failureAgentMsg struct{}
|
||||
|
||||
type successAgentMsg struct{}
|
||||
|
||||
// See PROTOCOL.agent, section 2.5.2.
|
||||
// See [PROTOCOL.agent], section 2.5.2.
|
||||
type requestIdentitiesAgentMsg struct{}
|
||||
|
||||
// See PROTOCOL.agent, section 2.5.2.
|
||||
// See [PROTOCOL.agent], section 2.5.2.
|
||||
type identitiesAnswerAgentMsg struct {
|
||||
NumKeys uint32
|
||||
Keys []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
// See PROTOCOL.agent, section 2.6.2.
|
||||
// See [PROTOCOL.agent], section 2.6.2.
|
||||
type signRequestAgentMsg struct {
|
||||
KeyBlob []byte
|
||||
Data []byte
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
// See PROTOCOL.agent, section 2.6.2.
|
||||
// See [PROTOCOL.agent], section 2.6.2.
|
||||
type signResponseAgentMsg struct {
|
||||
SigBlob []byte
|
||||
}
|
||||
|
||||
// AgentKey represents a protocol 2 key as defined in PROTOCOL.agent,
|
||||
// AgentKey represents a protocol 2 key as defined in [PROTOCOL.agent],
|
||||
// section 2.5.2.
|
||||
type AgentKey struct {
|
||||
blob []byte
|
||||
@@ -127,7 +124,7 @@ func parseAgentKey(in []byte) (out *AgentKey, rest []byte, ok bool) {
|
||||
}
|
||||
|
||||
// AgentClient provides a means to communicate with an ssh agent process based
|
||||
// on the protocol described in PROTOCOL.agent?rev=1.6.
|
||||
// on the protocol described in [PROTOCOL.agent]?rev=1.6.
|
||||
type AgentClient struct {
|
||||
// conn is typically represented by using a *net.UnixConn
|
||||
conn io.ReadWriter
|
||||
@@ -175,7 +172,7 @@ func (ac *AgentClient) sendAndReceive(req []byte) (reply interface{}, replyType
|
||||
}
|
||||
|
||||
// RequestIdentities queries the agent for protocol 2 keys as defined in
|
||||
// PROTOCOL.agent section 2.5.2.
|
||||
// [PROTOCOL.agent] section 2.5.2.
|
||||
func (ac *AgentClient) RequestIdentities() ([]*AgentKey, error) {
|
||||
req := marshal(agentRequestIdentities, requestIdentitiesAgentMsg{})
|
||||
|
||||
@@ -207,7 +204,7 @@ func (ac *AgentClient) RequestIdentities() ([]*AgentKey, error) {
|
||||
}
|
||||
|
||||
// SignRequest requests the signing of data by the agent using a protocol 2 key
|
||||
// as defined in PROTOCOL.agent section 2.6.2. Supported key types include
|
||||
// as defined in [PROTOCOL.agent] section 2.6.2. Supported key types include
|
||||
// *rsa.PublicKey, *dsa.PublicKey, *OpenSSHCertV01.
|
||||
func (ac *AgentClient) SignRequest(key interface{}, data []byte) ([]byte, error) {
|
||||
req := marshal(agentSignRequest, signRequestAgentMsg{
|
||||
|
||||
+9
-15
@@ -4,9 +4,6 @@
|
||||
|
||||
package ssh
|
||||
|
||||
// References
|
||||
// [PROTOCOL.certkeys]: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys
|
||||
|
||||
import (
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
@@ -16,11 +13,11 @@ import (
|
||||
|
||||
// String constants in [PROTOCOL.certkeys] for certificate algorithm names.
|
||||
const (
|
||||
certAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
|
||||
certAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
|
||||
certAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
|
||||
certAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
|
||||
certAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
||||
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
|
||||
CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
|
||||
CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
|
||||
CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
|
||||
CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
||||
)
|
||||
|
||||
// Certificate types are used to specify whether a certificate is for identification
|
||||
@@ -41,10 +38,7 @@ type tuple struct {
|
||||
}
|
||||
|
||||
// An OpenSSHCertV01 represents an OpenSSH certificate as defined in
|
||||
// [PROTOCOL.certkeys] rev 1.8. Supported formats include
|
||||
// ssh-rsa-cert-v01@openssh.com, ssh-dss-cert-v01@openssh.com,
|
||||
// ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com,
|
||||
// and ecdsa-sha2-nistp521-cert-v01@openssh.com.
|
||||
// [PROTOCOL.certkeys]?rev=1.8.
|
||||
type OpenSSHCertV01 struct {
|
||||
Nonce []byte
|
||||
Key interface{} // rsa, dsa, or ecdsa *PublicKey
|
||||
@@ -68,19 +62,19 @@ func parseOpenSSHCertV01(in []byte, algo string) (out *OpenSSHCertV01, rest []by
|
||||
}
|
||||
|
||||
switch algo {
|
||||
case certAlgoRSAv01:
|
||||
case CertAlgoRSAv01:
|
||||
var rsaPubKey *rsa.PublicKey
|
||||
if rsaPubKey, in, ok = parseRSA(in); !ok {
|
||||
return
|
||||
}
|
||||
cert.Key = rsaPubKey
|
||||
case certAlgoDSAv01:
|
||||
case CertAlgoDSAv01:
|
||||
var dsaPubKey *dsa.PublicKey
|
||||
if dsaPubKey, in, ok = parseDSA(in); !ok {
|
||||
return
|
||||
}
|
||||
cert.Key = dsaPubKey
|
||||
case certAlgoECDSA256v01, certAlgoECDSA384v01, certAlgoECDSA521v01:
|
||||
case CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01:
|
||||
var ecdsaPubKey *ecdsa.PublicKey
|
||||
if ecdsaPubKey, in, ok = parseECDSA(in); !ok {
|
||||
return
|
||||
|
||||
+15
-15
@@ -193,16 +193,16 @@ func serializeSignature(algoname string, sig []byte) []byte {
|
||||
// The corresponding private key to a public certificate is always a normal
|
||||
// private key. For signature serialization purposes, ensure we use the
|
||||
// proper key algorithm name in case the public cert algorithm name is passed.
|
||||
case certAlgoRSAv01:
|
||||
algoname = "ssh-rsa"
|
||||
case certAlgoDSAv01:
|
||||
algoname = "ssh-dss"
|
||||
case certAlgoECDSA256v01:
|
||||
algoname = "ecdsa-sha2-nistp256"
|
||||
case certAlgoECDSA384v01:
|
||||
algoname = "ecdsa-sha2-nistp384"
|
||||
case certAlgoECDSA521v01:
|
||||
algoname = "ecdsa-sha2-nistp521"
|
||||
case CertAlgoRSAv01:
|
||||
algoname = KeyAlgoRSA
|
||||
case CertAlgoDSAv01:
|
||||
algoname = KeyAlgoDSA
|
||||
case CertAlgoECDSA256v01:
|
||||
algoname = KeyAlgoECDSA256
|
||||
case CertAlgoECDSA384v01:
|
||||
algoname = KeyAlgoECDSA384
|
||||
case CertAlgoECDSA521v01:
|
||||
algoname = KeyAlgoECDSA521
|
||||
}
|
||||
length := stringLength(len(algoname))
|
||||
length += stringLength(len(sig))
|
||||
@@ -242,17 +242,17 @@ func serializePublickey(key interface{}) []byte {
|
||||
func algoName(key interface{}) string {
|
||||
switch key.(type) {
|
||||
case *rsa.PublicKey:
|
||||
return "ssh-rsa"
|
||||
return KeyAlgoRSA
|
||||
case *dsa.PublicKey:
|
||||
return "ssh-dss"
|
||||
return KeyAlgoDSA
|
||||
case *ecdsa.PublicKey:
|
||||
switch key.(*ecdsa.PublicKey).Params().BitSize {
|
||||
case 256:
|
||||
return "ecdsa-sha2-nistp256"
|
||||
return KeyAlgoECDSA256
|
||||
case 384:
|
||||
return "ecdsa-sha2-nistp384"
|
||||
return KeyAlgoECDSA384
|
||||
case 521:
|
||||
return "ecdsa-sha2-nistp521"
|
||||
return KeyAlgoECDSA521
|
||||
}
|
||||
case *OpenSSHCertV01:
|
||||
return algoName(key.(*OpenSSHCertV01).Key) + "-cert-v01@openssh.com"
|
||||
|
||||
@@ -10,5 +10,10 @@ family of application protocols. The most typical application level
|
||||
protocol is a remote shell and this is specifically implemented. However,
|
||||
the multiplexed nature of SSH is exposed to users that wish to support
|
||||
others.
|
||||
|
||||
References:
|
||||
[PROTOCOL.certkeys]: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys
|
||||
[PROTOCOL.agent]: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent
|
||||
[SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
|
||||
*/
|
||||
package ssh
|
||||
|
||||
+26
-26
@@ -16,11 +16,11 @@ import (
|
||||
|
||||
// Key types supported by OpenSSH 5.9
|
||||
const (
|
||||
keyAlgoRSA = "ssh-rsa"
|
||||
keyAlgoDSA = "ssh-dss"
|
||||
keyAlgoECDSA256 = "ecdsa-sha2-nistp256"
|
||||
keyAlgoECDSA384 = "ecdsa-sha2-nistp384"
|
||||
keyAlgoECDSA521 = "ecdsa-sha2-nistp521"
|
||||
KeyAlgoRSA = "ssh-rsa"
|
||||
KeyAlgoDSA = "ssh-dss"
|
||||
KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
|
||||
KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
|
||||
KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
|
||||
)
|
||||
|
||||
// parsePubKey parses a public key according to RFC 4253, section 6.6.
|
||||
@@ -31,13 +31,13 @@ func parsePubKey(in []byte) (out interface{}, rest []byte, ok bool) {
|
||||
}
|
||||
|
||||
switch string(algo) {
|
||||
case keyAlgoRSA:
|
||||
case KeyAlgoRSA:
|
||||
return parseRSA(in)
|
||||
case keyAlgoDSA:
|
||||
case KeyAlgoDSA:
|
||||
return parseDSA(in)
|
||||
case keyAlgoECDSA256, keyAlgoECDSA384, keyAlgoECDSA521:
|
||||
case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
|
||||
return parseECDSA(in)
|
||||
case certAlgoRSAv01, certAlgoDSAv01, certAlgoECDSA256v01, certAlgoECDSA384v01, certAlgoECDSA521v01:
|
||||
case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01:
|
||||
return parseOpenSSHCertV01(in, string(algo))
|
||||
}
|
||||
panic("ssh: unknown public key type")
|
||||
@@ -127,12 +127,12 @@ func parseECDSA(in []byte) (out *ecdsa.PublicKey, rest []byte, ok bool) {
|
||||
// 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(len(keyAlgoRSA))
|
||||
length := stringLength(len(KeyAlgoRSA))
|
||||
length += intLength(e)
|
||||
length += intLength(priv.N)
|
||||
|
||||
ret := make([]byte, length)
|
||||
r := marshalString(ret, []byte(keyAlgoRSA))
|
||||
r := marshalString(ret, []byte(KeyAlgoRSA))
|
||||
r = marshalInt(r, e)
|
||||
r = marshalInt(r, priv.N)
|
||||
|
||||
@@ -249,17 +249,17 @@ func ParseAuthorizedKey(in []byte) (out interface{}, comment string, options []s
|
||||
|
||||
field := string(in[:i])
|
||||
switch field {
|
||||
case keyAlgoRSA, keyAlgoDSA:
|
||||
case KeyAlgoRSA, KeyAlgoDSA:
|
||||
out, comment, ok = parseAuthorizedKey(in[i:])
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
case keyAlgoECDSA256, keyAlgoECDSA384, keyAlgoECDSA521:
|
||||
case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
|
||||
// We don't support these keys.
|
||||
in = rest
|
||||
continue
|
||||
case certAlgoRSAv01, certAlgoDSAv01,
|
||||
certAlgoECDSA256v01, certAlgoECDSA384v01, certAlgoECDSA521v01:
|
||||
case CertAlgoRSAv01, CertAlgoDSAv01,
|
||||
CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01:
|
||||
// We don't support these certificates.
|
||||
in = rest
|
||||
continue
|
||||
@@ -304,7 +304,7 @@ func ParseAuthorizedKey(in []byte) (out interface{}, comment string, options []s
|
||||
|
||||
field = string(in[:i])
|
||||
switch field {
|
||||
case keyAlgoRSA, keyAlgoDSA:
|
||||
case KeyAlgoRSA, KeyAlgoDSA:
|
||||
out, comment, ok = parseAuthorizedKey(in[i:])
|
||||
if ok {
|
||||
options = candidateOptions
|
||||
@@ -332,34 +332,34 @@ func MarshalAuthorizedKey(key interface{}) []byte {
|
||||
b := &bytes.Buffer{}
|
||||
switch keyType := key.(type) {
|
||||
case *rsa.PublicKey:
|
||||
b.WriteString(keyAlgoRSA)
|
||||
b.WriteString(KeyAlgoRSA)
|
||||
case *dsa.PublicKey:
|
||||
b.WriteString(keyAlgoDSA)
|
||||
b.WriteString(KeyAlgoDSA)
|
||||
case *ecdsa.PublicKey:
|
||||
switch keyType.Params().BitSize {
|
||||
case 256:
|
||||
b.WriteString(keyAlgoECDSA256)
|
||||
b.WriteString(KeyAlgoECDSA256)
|
||||
case 384:
|
||||
b.WriteString(keyAlgoECDSA384)
|
||||
b.WriteString(KeyAlgoECDSA384)
|
||||
case 521:
|
||||
b.WriteString(keyAlgoECDSA521)
|
||||
b.WriteString(KeyAlgoECDSA521)
|
||||
default:
|
||||
panic("unexpected key type")
|
||||
}
|
||||
case *OpenSSHCertV01:
|
||||
switch keyType.Key.(type) {
|
||||
case *rsa.PublicKey:
|
||||
b.WriteString(certAlgoRSAv01)
|
||||
b.WriteString(CertAlgoRSAv01)
|
||||
case *dsa.PublicKey:
|
||||
b.WriteString(certAlgoDSAv01)
|
||||
b.WriteString(CertAlgoDSAv01)
|
||||
case *ecdsa.PublicKey:
|
||||
switch keyType.Key.(*ecdsa.PublicKey).Params().BitSize {
|
||||
case 256:
|
||||
b.WriteString(certAlgoECDSA256v01)
|
||||
b.WriteString(CertAlgoECDSA256v01)
|
||||
case 384:
|
||||
b.WriteString(certAlgoECDSA384v01)
|
||||
b.WriteString(CertAlgoECDSA384v01)
|
||||
case 521:
|
||||
b.WriteString(certAlgoECDSA521v01)
|
||||
b.WriteString(CertAlgoECDSA521v01)
|
||||
default:
|
||||
panic("unexpected key type")
|
||||
}
|
||||
|
||||
+1
-2
@@ -13,8 +13,7 @@ import (
|
||||
)
|
||||
|
||||
// These are SSH message type numbers. They are scattered around several
|
||||
// documents but many were taken from
|
||||
// http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
|
||||
// documents but many were taken from [SSH-PARAMETERS].
|
||||
const (
|
||||
msgDisconnect = 1
|
||||
msgIgnore = 2
|
||||
|
||||
Reference in New Issue
Block a user