diff --git a/ssh/agent/client.go b/ssh/agent/client.go index 3f798e7..11d3094 100644 --- a/ssh/agent/client.go +++ b/ssh/agent/client.go @@ -25,6 +25,7 @@ import ( "math/big" "sync" + "golang.org/x/crypto/ed25519" "golang.org/x/crypto/ssh" ) @@ -423,6 +424,14 @@ type ecdsaKeyMsg struct { Constraints []byte `ssh:"rest"` } +type ed25519KeyMsg struct { + Type string `sshtype:"17|25"` + Pub []byte + Priv []byte + Comments string + Constraints []byte `ssh:"rest"` +} + // Insert adds a private key to the agent. func (c *client) insertKey(s interface{}, comment string, constraints []byte) error { var req []byte @@ -464,6 +473,14 @@ func (c *client) insertKey(s interface{}, comment string, constraints []byte) er Comments: comment, Constraints: constraints, }) + case *ed25519.PrivateKey: + req = ssh.Marshal(ed25519KeyMsg{ + Type: ssh.KeyAlgoED25519, + Pub: []byte(*k)[32:], + Priv: []byte(*k), + Comments: comment, + Constraints: constraints, + }) default: return fmt.Errorf("agent: unsupported key type %T", s) } @@ -510,6 +527,15 @@ type ecdsaCertMsg struct { Constraints []byte `ssh:"rest"` } +type ed25519CertMsg struct { + Type string `sshtype:"17|25"` + CertBytes []byte + Pub []byte + Priv []byte + Comments string + Constraints []byte `ssh:"rest"` +} + // Insert adds a private key to the agent. If a certificate is given, // that certificate is added instead as public key. func (c *client) Add(key AddedKey) error { @@ -566,6 +592,14 @@ func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string D: k.D, Comments: comment, }) + case ed25519.PrivateKey: + req = ssh.Marshal(ed25519CertMsg{ + Type: cert.Type(), + CertBytes: cert.Marshal(), + Pub: []byte(k)[32:], + Priv: []byte(k), + Comments: comment, + }) default: return fmt.Errorf("agent: unsupported key type %T", s) } diff --git a/ssh/agent/client_test.go b/ssh/agent/client_test.go index ec7198d..51a3e03 100644 --- a/ssh/agent/client_test.go +++ b/ssh/agent/client_test.go @@ -139,7 +139,7 @@ func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Ce } func TestAgent(t *testing.T) { - for _, keyType := range []string{"rsa", "dsa", "ecdsa"} { + for _, keyType := range []string{"rsa", "dsa", "ecdsa", "ed25519"} { testAgent(t, testPrivateKeys[keyType], nil, 0) } }