diff options
Diffstat (limited to 'vendor/golang.org/x/crypto/ssh/agent')
-rw-r--r-- | vendor/golang.org/x/crypto/ssh/agent/client.go | 55 | ||||
-rw-r--r-- | vendor/golang.org/x/crypto/ssh/agent/client_test.go | 42 | ||||
-rw-r--r-- | vendor/golang.org/x/crypto/ssh/agent/server.go | 35 | ||||
-rw-r--r-- | vendor/golang.org/x/crypto/ssh/agent/server_test.go | 21 | ||||
-rw-r--r-- | vendor/golang.org/x/crypto/ssh/agent/testdata_test.go | 2 |
5 files changed, 142 insertions, 13 deletions
diff --git a/vendor/golang.org/x/crypto/ssh/agent/client.go b/vendor/golang.org/x/crypto/ssh/agent/client.go index 3f798e719..ecfd7c58d 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/client.go +++ b/vendor/golang.org/x/crypto/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,7 +527,16 @@ type ecdsaCertMsg struct { Constraints []byte `ssh:"rest"` } -// Insert adds a private key to the agent. If a certificate is given, +type ed25519CertMsg struct { + Type string `sshtype:"17|25"` + CertBytes []byte + Pub []byte + Priv []byte + Comments string + Constraints []byte `ssh:"rest"` +} + +// Add 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 { var constraints []byte @@ -554,17 +580,28 @@ func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string }) case *dsa.PrivateKey: req = ssh.Marshal(dsaCertMsg{ - Type: cert.Type(), - CertBytes: cert.Marshal(), - X: k.X, - Comments: comment, + Type: cert.Type(), + CertBytes: cert.Marshal(), + X: k.X, + Comments: comment, + Constraints: constraints, }) case *ecdsa.PrivateKey: req = ssh.Marshal(ecdsaCertMsg{ - Type: cert.Type(), - CertBytes: cert.Marshal(), - D: k.D, - Comments: comment, + Type: cert.Type(), + CertBytes: cert.Marshal(), + D: k.D, + Comments: comment, + Constraints: constraints, + }) + case *ed25519.PrivateKey: + req = ssh.Marshal(ed25519CertMsg{ + Type: cert.Type(), + CertBytes: cert.Marshal(), + Pub: []byte(*k)[32:], + Priv: []byte(*k), + Comments: comment, + Constraints: constraints, }) default: return fmt.Errorf("agent: unsupported key type %T", s) diff --git a/vendor/golang.org/x/crypto/ssh/agent/client_test.go b/vendor/golang.org/x/crypto/ssh/agent/client_test.go index ec7198d54..230351fd2 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/client_test.go +++ b/vendor/golang.org/x/crypto/ssh/agent/client_test.go @@ -14,6 +14,7 @@ import ( "path/filepath" "strconv" "testing" + "time" "golang.org/x/crypto/ssh" ) @@ -139,7 +140,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) } } @@ -285,3 +286,42 @@ func testLockAgent(agent Agent, t *testing.T) { t.Errorf("Want 1 keys, got %v", keys) } } + +func TestAgentLifetime(t *testing.T) { + agent, _, cleanup := startAgent(t) + defer cleanup() + + for _, keyType := range []string{"rsa", "dsa", "ecdsa"} { + // Add private keys to the agent. + err := agent.Add(AddedKey{ + PrivateKey: testPrivateKeys[keyType], + Comment: "comment", + LifetimeSecs: 1, + }) + if err != nil { + t.Fatalf("add: %v", err) + } + // Add certs to the agent. + cert := &ssh.Certificate{ + Key: testPublicKeys[keyType], + ValidBefore: ssh.CertTimeInfinity, + CertType: ssh.UserCert, + } + cert.SignCert(rand.Reader, testSigners[keyType]) + err = agent.Add(AddedKey{ + PrivateKey: testPrivateKeys[keyType], + Certificate: cert, + Comment: "comment", + LifetimeSecs: 1, + }) + if err != nil { + t.Fatalf("add: %v", err) + } + } + time.Sleep(1100 * time.Millisecond) + if keys, err := agent.List(); err != nil { + t.Errorf("List: %v", err) + } else if len(keys) != 0 { + t.Errorf("Want 0 keys, got %v", len(keys)) + } +} diff --git a/vendor/golang.org/x/crypto/ssh/agent/server.go b/vendor/golang.org/x/crypto/ssh/agent/server.go index c562fa6e8..68a333fa5 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/server.go +++ b/vendor/golang.org/x/crypto/ssh/agent/server.go @@ -16,6 +16,7 @@ import ( "log" "math/big" + "golang.org/x/crypto/ed25519" "golang.org/x/crypto/ssh" ) @@ -175,6 +176,15 @@ func parseRSAKey(req []byte) (*AddedKey, error) { return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil } +func parseEd25519Key(req []byte) (*AddedKey, error) { + var k ed25519KeyMsg + if err := ssh.Unmarshal(req, &k); err != nil { + return nil, err + } + priv := ed25519.PrivateKey(k.Priv) + return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, nil +} + func parseDSAKey(req []byte) (*AddedKey, error) { var k dsaKeyMsg if err := ssh.Unmarshal(req, &k); err != nil { @@ -219,6 +229,23 @@ func unmarshalECDSA(curveName string, keyBytes []byte, privScalar *big.Int) (pri return priv, nil } +func parseEd25519Cert(req []byte) (*AddedKey, error) { + var k ed25519CertMsg + if err := ssh.Unmarshal(req, &k); err != nil { + return nil, err + } + pubKey, err := ssh.ParsePublicKey(k.CertBytes) + if err != nil { + return nil, err + } + priv := ed25519.PrivateKey(k.Priv) + cert, ok := pubKey.(*ssh.Certificate) + if !ok { + return nil, errors.New("agent: bad ED25519 certificate") + } + return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, nil +} + func parseECDSAKey(req []byte) (*AddedKey, error) { var k ecdsaKeyMsg if err := ssh.Unmarshal(req, &k); err != nil { @@ -230,7 +257,7 @@ func parseECDSAKey(req []byte) (*AddedKey, error) { return nil, err } - return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, nil + return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil } func parseRSACert(req []byte) (*AddedKey, error) { @@ -366,13 +393,17 @@ func (s *server) insertIdentity(req []byte) error { case ssh.KeyAlgoDSA: addedKey, err = parseDSAKey(req) case ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521: - addedKey, err = parseECDSACert(req) + addedKey, err = parseECDSAKey(req) + case ssh.KeyAlgoED25519: + addedKey, err = parseEd25519Key(req) case ssh.CertAlgoRSAv01: addedKey, err = parseRSACert(req) case ssh.CertAlgoDSAv01: addedKey, err = parseDSACert(req) case ssh.CertAlgoECDSA256v01, ssh.CertAlgoECDSA384v01, ssh.CertAlgoECDSA521v01: addedKey, err = parseECDSACert(req) + case ssh.CertAlgoED25519v01: + addedKey, err = parseEd25519Cert(req) default: return fmt.Errorf("agent: not implemented: %q", record.Type) } diff --git a/vendor/golang.org/x/crypto/ssh/agent/server_test.go b/vendor/golang.org/x/crypto/ssh/agent/server_test.go index c324d6c5a..ec9cdeeb5 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/server_test.go +++ b/vendor/golang.org/x/crypto/ssh/agent/server_test.go @@ -150,7 +150,25 @@ func TestKeyTypes(t *testing.T) { if err := addKeyToAgent(v); err != nil { t.Errorf("error adding key type %s, %v", k, err) } + if err := addCertToAgentSock(v, nil); err != nil { + t.Errorf("error adding key type %s, %v", k, err) + } + } +} + +func addCertToAgentSock(key crypto.PrivateKey, cert *ssh.Certificate) error { + a, b, err := netPipe() + if err != nil { + return err + } + agentServer := NewKeyring() + go ServeAgent(agentServer, a) + + agentClient := NewClient(b) + if err := agentClient.Add(AddedKey{PrivateKey: key, Certificate: cert}); err != nil { + return fmt.Errorf("add: %v", err) } + return verifyKey(agentClient) } func addCertToAgent(key crypto.PrivateKey, cert *ssh.Certificate) error { @@ -182,5 +200,8 @@ func TestCertTypes(t *testing.T) { if err := addCertToAgent(testPrivateKeys[keyType], cert); err != nil { t.Fatalf("%v", err) } + if err := addCertToAgentSock(testPrivateKeys[keyType], cert); err != nil { + t.Fatalf("%v", err) + } } } diff --git a/vendor/golang.org/x/crypto/ssh/agent/testdata_test.go b/vendor/golang.org/x/crypto/ssh/agent/testdata_test.go index b7a8781e1..cc42a87cb 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/testdata_test.go +++ b/vendor/golang.org/x/crypto/ssh/agent/testdata_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: +// IMPLEMENTATION NOTE: To avoid a package loop, this file is in three places: // ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three // instances. |