crypto/ssh: allow identities to be constrained.

The ssh-agent protocol allows the usage of keys and certs added to a
given agent to be constrained in certain ways. The only constraints
currently supported are lifetime (keys expire after some number of
seconds) and confirmation (the agent requires user confirmation before
performing any operations with the private key).

Change-Id: Idba5760db929805bf3da43fdcaca53ae6c479ca4
Reviewed-on: https://go-review.googlesource.com/12260
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Peter Moody <pmoody@uber.com>
This commit is contained in:
Peter Moody
2015-07-16 17:35:58 +00:00
committed by Adam Langley
parent 4d8f0cfeca
commit 7d5b0be716
6 changed files with 161 additions and 90 deletions
+19 -10
View File
@@ -78,14 +78,14 @@ func startAgent(t *testing.T) (client Agent, socket string, cleanup func()) {
}
}
func testAgent(t *testing.T, key interface{}, cert *ssh.Certificate) {
func testAgent(t *testing.T, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
agent, _, cleanup := startAgent(t)
defer cleanup()
testAgentInterface(t, agent, key, cert)
testAgentInterface(t, agent, key, cert, lifetimeSecs)
}
func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate) {
func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
signer, err := ssh.NewSignerFromKey(key)
if err != nil {
t.Fatalf("NewSignerFromKey(%T): %v", key, err)
@@ -100,10 +100,15 @@ func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Ce
// Attempt to insert the key, with certificate if specified.
var pubKey ssh.PublicKey
if cert != nil {
err = agent.Add(key, cert, "comment")
err = agent.Add(AddedKey{
PrivateKey: key,
Certificate: cert,
Comment: "comment",
LifetimeSecs: lifetimeSecs,
})
pubKey = cert
} else {
err = agent.Add(key, nil, "comment")
err = agent.Add(AddedKey{PrivateKey: key, Comment: "comment", LifetimeSecs: lifetimeSecs})
pubKey = signer.PublicKey()
}
if err != nil {
@@ -135,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"} {
testAgent(t, testPrivateKeys[keyType], nil)
testAgent(t, testPrivateKeys[keyType], nil, 0)
}
}
@@ -147,7 +152,11 @@ func TestCert(t *testing.T) {
}
cert.SignCert(rand.Reader, testSigners["ecdsa"])
testAgent(t, testPrivateKeys["rsa"], cert)
testAgent(t, testPrivateKeys["rsa"], cert, 0)
}
func TestConstraints(t *testing.T) {
testAgent(t, testPrivateKeys["rsa"], nil, 3600 /* lifetime in seconds */)
}
// netPipe is analogous to net.Pipe, but it uses a real net.Conn, and
@@ -185,7 +194,7 @@ func TestAuth(t *testing.T) {
agent, _, cleanup := startAgent(t)
defer cleanup()
if err := agent.Add(testPrivateKeys["rsa"], nil, "comment"); err != nil {
if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["rsa"], Comment: "comment"}); err != nil {
t.Errorf("Add: %v", err)
}
@@ -223,10 +232,10 @@ func TestLockClient(t *testing.T) {
}
func testLockAgent(agent Agent, t *testing.T) {
if err := agent.Add(testPrivateKeys["rsa"], nil, "comment 1"); err != nil {
if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["rsa"], Comment: "comment 1"}); err != nil {
t.Errorf("Add: %v", err)
}
if err := agent.Add(testPrivateKeys["dsa"], nil, "comment dsa"); err != nil {
if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["dsa"], Comment: "comment dsa"}); err != nil {
t.Errorf("Add: %v", err)
}
if keys, err := agent.List(); err != nil {