diff options
| author | Adam Eijdenberg <adam@continusec.com> | 2017-05-16 13:11:29 +1000 |
|---|---|---|
| committer | Han-Wen Nienhuys <hanwen@google.com> | 2017-05-23 10:10:29 +0000 |
| commit | 7e9105388ebff089b3f99f0ef676ea55a6da3a7e (patch) | |
| tree | 3897b171620dad13e27364c6365e928a00d10b9b /ssh/test/cert_test.go | |
| parent | 6c586e17d90a7d08bbbc4069984180dce3b04117 (diff) | |
| download | go-x-crypto-7e9105388ebff089b3f99f0ef676ea55a6da3a7e.tar.xz | |
x/crypto/ssh: fix host certificate principal evaluation to check for hostname only
SSH host certificates are expected to contain hostnames only,
not "host:port" format.
This change allows Go clients to connect to OpenSSH servers that
use host certificates.
Note, this change will break any clients that use ssh.NewClientConn()
with an `addr` that is not in `host:port` format (they will see a
"missing port in address" error).
Fixes bug 20273.
Change-Id: I5a306c6b7b419a737e1f0f9c5ca8c585e21a45a4
Reviewed-on: https://go-review.googlesource.com/43475
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'ssh/test/cert_test.go')
| -rw-r--r-- | ssh/test/cert_test.go | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/ssh/test/cert_test.go b/ssh/test/cert_test.go index bc83e4f..b231dd8 100644 --- a/ssh/test/cert_test.go +++ b/ssh/test/cert_test.go @@ -7,12 +7,14 @@ package test import ( + "bytes" "crypto/rand" "testing" "golang.org/x/crypto/ssh" ) +// Test both logging in with a cert, and also that the certificate presented by an OpenSSH host can be validated correctly func TestCertLogin(t *testing.T) { s := newServer(t) defer s.Shutdown() @@ -36,13 +38,40 @@ func TestCertLogin(t *testing.T) { } conf := &ssh.ClientConfig{ - User: username(), - HostKeyCallback: ssh.InsecureIgnoreHostKey(), + User: username(), + HostKeyCallback: (&ssh.CertChecker{ + IsHostAuthority: func(pk ssh.PublicKey, addr string) bool { + return bytes.Equal(pk.Marshal(), testPublicKeys["ca"].Marshal()) + }, + }).CheckHostKey, } conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner)) - client, err := s.TryDial(conf) - if err != nil { - t.Fatalf("TryDial: %v", err) + + for _, test := range []struct { + addr string + succeed bool + }{ + {addr: "host.example.com:22", succeed: true}, + {addr: "host.example.com:10000", succeed: true}, // non-standard port must be OK + {addr: "host.example.com", succeed: false}, // port must be specified + {addr: "host.ex4mple.com:22", succeed: false}, // wrong host + } { + client, err := s.TryDialWithAddr(conf, test.addr) + + // Always close client if opened successfully + if err == nil { + client.Close() + } + + // Now evaluate whether the test failed or passed + if test.succeed { + if err != nil { + t.Fatalf("TryDialWithAddr: %v", err) + } + } else { + if err == nil { + t.Fatalf("TryDialWithAddr, unexpected success") + } + } } - client.Close() } |
