diff options
author | Niall Sheridan <nsheridan@gmail.com> | 2016-10-08 16:02:50 -0500 |
---|---|---|
committer | Niall Sheridan <nsheridan@gmail.com> | 2016-10-08 16:02:50 -0500 |
commit | baf7141d1dd0f99d561a2197a909c66dd389809d (patch) | |
tree | 92c176f713b0b28893344261b1e567db5e30ba79 /vendor/golang.org/x/crypto/ssh | |
parent | 696aebffe56853345d679d4d2b3051236423c6db (diff) |
Update dependencies
Diffstat (limited to 'vendor/golang.org/x/crypto/ssh')
-rw-r--r-- | vendor/golang.org/x/crypto/ssh/agent/keyring.go | 53 | ||||
-rw-r--r-- | vendor/golang.org/x/crypto/ssh/handshake.go | 11 | ||||
-rw-r--r-- | vendor/golang.org/x/crypto/ssh/keys.go | 34 |
3 files changed, 86 insertions, 12 deletions
diff --git a/vendor/golang.org/x/crypto/ssh/agent/keyring.go b/vendor/golang.org/x/crypto/ssh/agent/keyring.go index 12ffa82..a6ba06a 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/keyring.go +++ b/vendor/golang.org/x/crypto/ssh/agent/keyring.go @@ -11,6 +11,7 @@ import ( "errors" "fmt" "sync" + "time" "golang.org/x/crypto/ssh" ) @@ -18,6 +19,7 @@ import ( type privKey struct { signer ssh.Signer comment string + expire *time.Time } type keyring struct { @@ -48,15 +50,9 @@ func (r *keyring) RemoveAll() error { return nil } -// Remove removes all identities with the given public key. -func (r *keyring) Remove(key ssh.PublicKey) error { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - return errLocked - } - - want := key.Marshal() +// removeLocked does the actual key removal. The caller must already be holding the +// keyring mutex. +func (r *keyring) removeLocked(want []byte) error { found := false for i := 0; i < len(r.keys); { if bytes.Equal(r.keys[i].signer.PublicKey().Marshal(), want) { @@ -75,7 +71,18 @@ func (r *keyring) Remove(key ssh.PublicKey) error { return nil } -// Lock locks the agent. Sign and Remove will fail, and List will empty an empty list. +// Remove removes all identities with the given public key. +func (r *keyring) Remove(key ssh.PublicKey) error { + r.mu.Lock() + defer r.mu.Unlock() + if r.locked { + return errLocked + } + + return r.removeLocked(key.Marshal()) +} + +// Lock locks the agent. Sign and Remove will fail, and List will return an empty list. func (r *keyring) Lock(passphrase []byte) error { r.mu.Lock() defer r.mu.Unlock() @@ -104,6 +111,17 @@ func (r *keyring) Unlock(passphrase []byte) error { return nil } +// expireKeysLocked removes expired keys from the keyring. If a key was added +// with a lifetimesecs contraint and seconds >= lifetimesecs seconds have +// ellapsed, it is removed. The caller *must* be holding the keyring mutex. +func (r *keyring) expireKeysLocked() { + for _, k := range r.keys { + if k.expire != nil && time.Now().After(*k.expire) { + r.removeLocked(k.signer.PublicKey().Marshal()) + } + } +} + // List returns the identities known to the agent. func (r *keyring) List() ([]*Key, error) { r.mu.Lock() @@ -113,6 +131,7 @@ func (r *keyring) List() ([]*Key, error) { return nil, nil } + r.expireKeysLocked() var ids []*Key for _, k := range r.keys { pub := k.signer.PublicKey() @@ -146,7 +165,17 @@ func (r *keyring) Add(key AddedKey) error { } } - r.keys = append(r.keys, privKey{signer, key.Comment}) + p := privKey{ + signer: signer, + comment: key.Comment, + } + + if key.LifetimeSecs > 0 { + t := time.Now().Add(time.Duration(key.LifetimeSecs) * time.Second) + p.expire = &t + } + + r.keys = append(r.keys, p) return nil } @@ -159,6 +188,7 @@ func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) { return nil, errLocked } + r.expireKeysLocked() wanted := key.Marshal() for _, k := range r.keys { if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) { @@ -176,6 +206,7 @@ func (r *keyring) Signers() ([]ssh.Signer, error) { return nil, errLocked } + r.expireKeysLocked() s := make([]ssh.Signer, 0, len(r.keys)) for _, k := range r.keys { s = append(s, k.signer) diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go index ae26191..37d42e4 100644 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ b/vendor/golang.org/x/crypto/ssh/handshake.go @@ -371,7 +371,16 @@ func (t *handshakeTransport) enterKeyExchangeLocked(otherInitPacket []byte) erro } // We don't send FirstKexFollows, but we handle receiving it. - if otherInit.FirstKexFollows && algs.kex != otherInit.KexAlgos[0] { + // + // RFC 4253 section 7 defines the kex and the agreement method for + // first_kex_packet_follows. It states that the guessed packet + // should be ignored if the "kex algorithm and/or the host + // key algorithm is guessed wrong (server and client have + // different preferred algorithm), or if any of the other + // algorithms cannot be agreed upon". The other algorithms have + // already been checked above so the kex algorithm and host key + // algorithm are checked here. + if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) { // other side sent a kex message for the wrong algorithm, // which we have to ignore. if _, err := t.conn.readPacket(); err != nil { diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index 0324e12..e13cf9c 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -281,6 +281,12 @@ type PublicKey interface { Verify(data []byte, sig *Signature) error } +// CryptoPublicKey, if implemented by a PublicKey, +// returns the underlying crypto.PublicKey form of the key. +type CryptoPublicKey interface { + CryptoPublicKey() crypto.PublicKey +} + // A Signer can create signatures that verify against a public key. type Signer interface { // PublicKey returns an associated PublicKey instance. @@ -348,6 +354,10 @@ func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error { return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig.Blob) } +func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey { + return (*rsa.PublicKey)(r) +} + type dsaPublicKey dsa.PublicKey func (r *dsaPublicKey) Type() string { @@ -416,6 +426,10 @@ func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error { return errors.New("ssh: signature did not verify") } +func (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey { + return (*dsa.PublicKey)(k) +} + type dsaPrivateKey struct { *dsa.PrivateKey } @@ -509,6 +523,10 @@ func (key ed25519PublicKey) Verify(b []byte, sig *Signature) error { return nil } +func (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey { + return ed25519.PublicKey(k) +} + func supportedEllipticCurve(curve elliptic.Curve) bool { return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521() } @@ -604,6 +622,10 @@ func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error { return errors.New("ssh: signature did not verify") } +func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey { + return (*ecdsa.PublicKey)(k) +} + // NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey, // *ecdsa.PrivateKey or any other crypto.Signer and returns a corresponding // Signer instance. ECDSA keys must use P-256, P-384 or P-521. @@ -731,6 +753,14 @@ func ParsePrivateKey(pemBytes []byte) (Signer, error) { return NewSignerFromKey(key) } +// encryptedBlock tells whether a private key is +// encrypted by examining its Proc-Type header +// for a mention of ENCRYPTED +// according to RFC 1421 Section 4.6.1.1. +func encryptedBlock(block *pem.Block) bool { + return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED") +} + // ParseRawPrivateKey returns a private key from a PEM encoded private key. It // supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys. func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) { @@ -739,6 +769,10 @@ func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) { return nil, errors.New("ssh: no key found") } + if encryptedBlock(block) { + return nil, errors.New("ssh: cannot decode encrypted private keys") + } + switch block.Type { case "RSA PRIVATE KEY": return x509.ParsePKCS1PrivateKey(block.Bytes) |